From ee54e63b8607d57c7abc186762e0e228ed850ed6 Mon Sep 17 00:00:00 2001 From: Christoph Deppisch Date: Tue, 20 Feb 2024 16:04:10 +0100 Subject: [PATCH] fix(#5097): Remove secondary IntegrationPlatform in favor of using IntegrationProfile - Remove secondary IntegrationPlatform mode - Reduce logic to a single IntegrationPlatform per operator instance - IntegrationPlatforms matching the operatorID do have precedence when searching for local platforms - Introduce IntegrationProfile custom resource definition - Let user customize a subset of IntegrationPlatform settings in IntegrationProfile - Load IntegrationProfile settings when integration resource is annotated to select the profile - Save trait configuration used to build the integration kit on the resource spec for future reference --- .../kamel-cleanup/clean-orphan-resources.sh | 2 +- .../ROOT/pages/contributing/uninstalling.adoc | 1 + .../pages/installation/advanced/multi.adoc | 35 +- .../ROOT/partials/apis/camel-k-crds.adoc | 296 ++ e2e/advanced/integration_profile_test.go | 213 + e2e/advanced/operator_id_filtering_test.go | 16 +- e2e/advanced/secondary_platform_test.go | 77 - e2e/install/upgrade/helm_upgrade_test.go | 17 +- e2e/support/test_support.go | 92 +- e2e/support/util/dump.go | 15 + .../camel-k/crds/crd-integration-profile.yaml | 3559 +++++++++++++++++ .../templates/operator-cluster-roles.yaml | 7 +- helm/camel-k/templates/operator-role.yaml | 3 + pkg/apis/camel/v1/common_types.go | 6 +- pkg/apis/camel/v1/common_types_support.go | 57 +- .../camel/v1/common_types_support_test.go | 68 + .../camel/v1/integrationplatform_types.go | 2 - pkg/apis/camel/v1/integrationprofile_types.go | 138 + .../v1/integrationprofile_types_support.go | 191 + pkg/apis/camel/v1/register.go | 2 + pkg/apis/camel/v1/zz_generated.deepcopy.go | 159 + .../camel/v1/integrationprofile.go | 220 + .../camel/v1/integrationprofilebuildspec.go | 90 + .../camel/v1/integrationprofilecondition.go | 91 + .../camel/v1/integrationprofilekameletspec.go | 45 + .../camel/v1/integrationprofilespec.go | 58 + .../camel/v1/integrationprofilestatus.go | 92 + pkg/client/camel/applyconfiguration/utils.go | 12 + .../versioned/typed/camel/v1/camel_client.go | 5 + .../typed/camel/v1/fake/fake_camel_client.go | 4 + .../camel/v1/fake/fake_integrationprofile.go | 190 + .../typed/camel/v1/generated_expansion.go | 2 + .../typed/camel/v1/integrationprofile.go | 257 ++ .../camel/v1/integrationprofile.go | 91 + .../externalversions/camel/v1/interface.go | 7 + .../informers/externalversions/generic.go | 2 + .../listers/camel/v1/expansion_generated.go | 8 + .../listers/camel/v1/integrationprofile.go | 100 + pkg/cmd/kamelet_add_repo.go | 8 +- pkg/cmd/kamelet_remove_repo.go | 2 +- pkg/cmd/reset.go | 2 +- pkg/cmd/run.go | 79 +- pkg/cmd/uninstall.go | 25 + pkg/cmd/uninstall_test.go | 4 +- pkg/controller/add_integrationprofile.go | 26 + pkg/controller/build/build_controller.go | 2 +- pkg/controller/catalog/initialize.go | 3 +- pkg/controller/integration/build_kit.go | 3 +- .../integration/integration_controller.go | 72 +- pkg/controller/integration/kits.go | 21 +- pkg/controller/integration/kits_test.go | 22 +- pkg/controller/integration/monitor.go | 38 +- pkg/controller/integrationkit/build.go | 9 + .../integrationkit_controller.go | 8 +- pkg/controller/integrationplatform/create.go | 5 +- .../integrationplatform/initialize.go | 41 +- pkg/controller/integrationprofile/action.go | 54 + .../integrationprofile/initialize.go | 58 + .../integrationprofile_controller.go | 216 + pkg/controller/integrationprofile/log.go | 23 + pkg/controller/integrationprofile/monitor.go | 47 + pkg/controller/kameletbinding/monitor.go | 9 +- pkg/controller/pipe/monitor.go | 43 +- pkg/event/manager.go | 36 + pkg/install/cluster.go | 11 + pkg/install/platform.go | 2 +- pkg/platform/defaults.go | 13 +- pkg/platform/operator.go | 21 +- pkg/platform/platform.go | 147 +- pkg/platform/profile.go | 138 + pkg/platform/profile_test.go | 322 ++ .../camel.apache.org_integrationprofiles.yaml | 3559 +++++++++++++++++ pkg/resources/config/crd/kustomization.yaml | 1 + .../rbac/descoped/operator-cluster-role.yaml | 2 + .../config/rbac/namespaced/operator-role.yaml | 2 + .../operator-cluster-role-openshift.yaml | 1 + .../namespaced/operator-role-openshift.yaml | 1 + .../config/rbac/user-cluster-role.yaml | 2 + .../bases/camel_v1_integrationprofile.yaml | 27 + .../config/samples/kustomization.yaml | 1 + ...r-global-platform-viewer-role-binding.yaml | 2 +- .../user-global-platform-viewer-role.yaml | 3 +- pkg/resources/resources_test.go | 1 + pkg/trait/camel.go | 3 + pkg/trait/container.go | 13 + pkg/trait/platform.go | 2 +- pkg/trait/quarkus.go | 42 +- pkg/trait/trait.go | 7 + pkg/trait/trait_configure.go | 5 + pkg/trait/trait_types.go | 2 + pkg/trait/util.go | 93 +- pkg/util/digest/digest.go | 8 + pkg/util/kubernetes/client.go | 11 + pkg/util/log/log.go | 10 + script/gen_crd.sh | 3 +- script/prepare-operators.sh | 2 + 96 files changed, 11116 insertions(+), 427 deletions(-) create mode 100644 e2e/advanced/integration_profile_test.go delete mode 100644 e2e/advanced/secondary_platform_test.go create mode 100644 helm/camel-k/crds/crd-integration-profile.yaml create mode 100644 pkg/apis/camel/v1/integrationprofile_types.go create mode 100644 pkg/apis/camel/v1/integrationprofile_types_support.go create mode 100644 pkg/client/camel/applyconfiguration/camel/v1/integrationprofile.go create mode 100644 pkg/client/camel/applyconfiguration/camel/v1/integrationprofilebuildspec.go create mode 100644 pkg/client/camel/applyconfiguration/camel/v1/integrationprofilecondition.go create mode 100644 pkg/client/camel/applyconfiguration/camel/v1/integrationprofilekameletspec.go create mode 100644 pkg/client/camel/applyconfiguration/camel/v1/integrationprofilespec.go create mode 100644 pkg/client/camel/applyconfiguration/camel/v1/integrationprofilestatus.go create mode 100644 pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_integrationprofile.go create mode 100644 pkg/client/camel/clientset/versioned/typed/camel/v1/integrationprofile.go create mode 100644 pkg/client/camel/informers/externalversions/camel/v1/integrationprofile.go create mode 100644 pkg/client/camel/listers/camel/v1/integrationprofile.go create mode 100644 pkg/controller/add_integrationprofile.go create mode 100644 pkg/controller/integrationprofile/action.go create mode 100644 pkg/controller/integrationprofile/initialize.go create mode 100644 pkg/controller/integrationprofile/integrationprofile_controller.go create mode 100644 pkg/controller/integrationprofile/log.go create mode 100644 pkg/controller/integrationprofile/monitor.go create mode 100644 pkg/platform/profile.go create mode 100644 pkg/platform/profile_test.go create mode 100644 pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml create mode 100644 pkg/resources/config/samples/bases/camel_v1_integrationprofile.yaml diff --git a/.github/actions/kamel-cleanup/clean-orphan-resources.sh b/.github/actions/kamel-cleanup/clean-orphan-resources.sh index 5ac6c361cf..f217096a1d 100755 --- a/.github/actions/kamel-cleanup/clean-orphan-resources.sh +++ b/.github/actions/kamel-cleanup/clean-orphan-resources.sh @@ -20,7 +20,7 @@ set +e -resourcetypes="integrations integrationkits integrationplatforms camelcatalogs kamelets builds pipes kameletbindings" +resourcetypes="integrations integrationkits integrationplatforms integrationprofiles camelcatalogs kamelets builds pipes kameletbindings" # # Loop through the resource types diff --git a/docs/modules/ROOT/pages/contributing/uninstalling.adoc b/docs/modules/ROOT/pages/contributing/uninstalling.adoc index 88f376f39e..c236dbee72 100644 --- a/docs/modules/ROOT/pages/contributing/uninstalling.adoc +++ b/docs/modules/ROOT/pages/contributing/uninstalling.adoc @@ -26,4 +26,5 @@ customresourcedefinition.apiextensions.k8s.io/camelcatalogs.camel.apache.org customresourcedefinition.apiextensions.k8s.io/integrationkits.camel.apache.org 2020-05-28T20:31:39Z customresourcedefinition.apiextensions.k8s.io/integrationplatforms.camel.apache.org 2020-05-28T20:31:39Z customresourcedefinition.apiextensions.k8s.io/integrations.camel.apache.org 2020-05-28T20:31:39Z +customresourcedefinition.apiextensions.k8s.io/integrationprofiles.camel.apache.org 2020-05-28T20:31:39Z ---- diff --git a/docs/modules/ROOT/pages/installation/advanced/multi.adoc b/docs/modules/ROOT/pages/installation/advanced/multi.adoc index 9a8e409159..048f29a1c0 100644 --- a/docs/modules/ROOT/pages/installation/advanced/multi.adoc +++ b/docs/modules/ROOT/pages/installation/advanced/multi.adoc @@ -49,21 +49,23 @@ operator id: kubectl annotate integration timer-to-log camel.apache.org/operator.id=operator-2 --overwrite ---- -[[advanced-installation-multiple-platforms]] -== Configuring Multiple Integration Platforms +[[advanced-installation-integration-profile]] +== Apply custom IntegrationProfile settings Any running Camel K integration is associated to a shared IntegrationPlatform resource that contains general configuration options. -The integration platform is located in the integration namespace (or also in the operator namespace, in case of global installation) -and typically only one ("primary", see later) integration platform is allowed to obtain a "Ready" state in a namespace, while others get the "Duplicate" state (i.e. IntegrationPlatform resources -are somewhat "singleton" in a namespace). +The integration platform is located in the operator namespace and typically uses the same name as the operator id that this platform belongs to. +Each Camel K operator uses exactly one single integration platform in a "Ready" state. +IntegrationPlatform resources are somewhat "singleton" in a namespace and belong to a single operator instance. -There's a way to allow two or more integration platforms to get a "Ready" state in a namespace and for them to be used by integrations: -platforms can be marked with the annotation `camel.apache.org/secondary.platform=true`. -That annotation marks the platform as *secondary* so that it will never be used as default platform during the reconciliation of an integration, -unless explicitly selected (any resource belonging to the "camel.apache.org" group can select a particular integration platform). -Secondary platforms are also allowed to reach the "Ready" state without becoming "Duplicate". +There's a way to allow customizations regarding the integration configuration. +Users may add IntegrationProfile resources to an individual namespace. +The profile holds custom integration platform settings for them to be used by integrations. +The IntegrationProfile resource allows only a subset of the IntegrationPlatform settings for customization. -To specify which integration platform should be used to reconcile a specific CR, the CR can be annotated like in the following example: +The custom IntegrationProfile resource uses the operator id as an annotation to bind its reconciliation to an operator instance. +Also, the profile must be explicitly selected by an annotation referencing the integration profile name (any resource belonging to the "camel.apache.org" group can select a particular profile configuration). + +To specify which profile should be used for an integration, the resource can be annotated like in the following example: [source,yaml] ---- @@ -71,12 +73,13 @@ kind: Integration apiVersion: camel.apache.org/v1 metadata: annotations: - camel.apache.org/platform.id: my-platform-name + camel.apache.org/integration-profile.id: my-profile-name # ... ---- -The value of the `camel.apache.org/platform.id` annotation must match the name of an IntegrationPlatform custom resource, in the annotated resource namespace or -also in the operator namespace. +The value of the `camel.apache.org/integration-profile.id` annotation must match the name of an IntegrationProfile custom resource. +The profile gets automatically resolved from the annotated resource namespace or from the operator namespace. +In case you need to explicitly set the integration profile namespace you can do so with the `camel.apache.org/integration-profile.namespace` annotation. -The selection of a secondary IntegrationPlatform enables new configuration scenarios, for example, sharing global configuration options for groups of integrations, or also -providing per-operator specific configuration options e.g. when you install multiple global operators in the same namespace. +The selection of a IntegrationProfile enables new configuration scenarios, for example, sharing global configuration options for groups of integrations, or also +providing per-operator specific configuration options e.g. when you install multiple global operators in the cluster. diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index e8e5bae6e7..6dd95700e2 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -219,6 +219,49 @@ Refer to the Kubernetes API documentation for the fields of the `metadata` field +|=== + +[#_camel_apache_org_v1_IntegrationProfile] +=== IntegrationProfile + +IntegrationProfile is the resource used to apply user defined settings to the Camel K operator behavior. +It defines the behavior of all Custom Resources (`IntegrationKit`, `Integration`, `Kamelet`) in the given namespace. + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`apiVersion` + +string +|`camel.apache.org/v1` + +|`kind` + +string +|`IntegrationProfile` +|`metadata` + +*https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#objectmeta-v1-meta[Kubernetes meta/v1.ObjectMeta]* +| + + + + +Refer to the Kubernetes API documentation for the fields of the `metadata` field. +|`spec` + +*xref:#_camel_apache_org_v1_IntegrationProfileSpec[IntegrationProfileSpec]* +| + + + + +|`status` + +*xref:#_camel_apache_org_v1_IntegrationProfileStatus[IntegrationProfileStatus]* +| + + + + + |=== [#_camel_apache_org_v1_Kamelet] @@ -2978,6 +3021,254 @@ map[string]string generic information related to the build of Camel K operator software +|=== + +[#_camel_apache_org_v1_IntegrationProfileBuildSpec] +=== IntegrationProfileBuildSpec + +*Appears on:* + +* <<#_camel_apache_org_v1_IntegrationProfileSpec, IntegrationProfileSpec>> + +IntegrationProfileBuildSpec contains profile related build information. +This configuration can be used to tune the behavior of the Integration/IntegrationKit image builds. + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`runtimeVersion` + +string +| + + +the Camel K Runtime dependency version + +|`runtimeProvider` + +*xref:#_camel_apache_org_v1_RuntimeProvider[RuntimeProvider]* +| + + +the runtime used. Likely Camel Quarkus (we used to have main runtime which has been discontinued since version 1.5) + +|`baseImage` + +string +| + + +a base image that can be used as base layer for all images. +It can be useful if you want to provide some custom base image with further utility software + +|`registry` + +*xref:#_camel_apache_org_v1_RegistrySpec[RegistrySpec]* +| + + +the image registry used to push/pull Integration images + +|`timeout` + +*https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#duration-v1-meta[Kubernetes meta/v1.Duration]* +| + + +how much time to wait before time out the pipeline process + +|`maven` + +*xref:#_camel_apache_org_v1_MavenSpec[MavenSpec]* +| + + +Maven configuration used to build the Camel/Camel-Quarkus applications + + +|=== + +[#_camel_apache_org_v1_IntegrationProfileCondition] +=== IntegrationProfileCondition + +*Appears on:* + +* <<#_camel_apache_org_v1_IntegrationProfileStatus, IntegrationProfileStatus>> + +IntegrationProfileCondition describes the state of a resource at a certain point. + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`type` + +*xref:#_camel_apache_org_v1_IntegrationProfileConditionType[IntegrationProfileConditionType]* +| + + +Type of integration condition. + +|`status` + +*https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#conditionstatus-v1-core[Kubernetes core/v1.ConditionStatus]* +| + + +Status of the condition, one of True, False, Unknown. + +|`lastUpdateTime` + +*https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#time-v1-meta[Kubernetes meta/v1.Time]* +| + + +The last time this condition was updated. + +|`lastTransitionTime` + +*https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.27/#time-v1-meta[Kubernetes meta/v1.Time]* +| + + +Last time the condition transitioned from one status to another. + +|`reason` + +string +| + + +The reason for the condition's last transition. + +|`message` + +string +| + + +A human-readable message indicating details about the transition. + + +|=== + +[#_camel_apache_org_v1_IntegrationProfileConditionType] +=== IntegrationProfileConditionType(`string` alias) + +*Appears on:* + +* <<#_camel_apache_org_v1_IntegrationProfileCondition, IntegrationProfileCondition>> + +IntegrationProfileConditionType defines the type of condition. + + +[#_camel_apache_org_v1_IntegrationProfileKameletSpec] +=== IntegrationProfileKameletSpec + +*Appears on:* + +* <<#_camel_apache_org_v1_IntegrationProfileSpec, IntegrationProfileSpec>> + +IntegrationProfileKameletSpec define the behavior for all the Kamelets controller by the IntegrationProfile. + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`repositories` + +*xref:#_camel_apache_org_v1_KameletRepositorySpec[[\]KameletRepositorySpec]* +| + + +remote repository used to retrieve Kamelet catalog + + +|=== + +[#_camel_apache_org_v1_IntegrationProfilePhase] +=== IntegrationProfilePhase(`string` alias) + +*Appears on:* + +* <<#_camel_apache_org_v1_IntegrationProfileStatus, IntegrationProfileStatus>> + +IntegrationProfilePhase is the phase of an IntegrationProfile. + + +[#_camel_apache_org_v1_IntegrationProfileSpec] +=== IntegrationProfileSpec + +*Appears on:* + +* <<#_camel_apache_org_v1_IntegrationProfile, IntegrationProfile>> +* <<#_camel_apache_org_v1_IntegrationProfileStatus, IntegrationProfileStatus>> + +IntegrationProfileSpec applies user defined settings to the IntegrationProfile. + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`build` + +*xref:#_camel_apache_org_v1_IntegrationProfileBuildSpec[IntegrationProfileBuildSpec]* +| + + +specify how to build the Integration/IntegrationKits + +|`traits` + +*xref:#_camel_apache_org_v1_Traits[Traits]* +| + + +list of traits to be executed for all the Integration/IntegrationKits built from this IntegrationProfile + +|`kamelet` + +*xref:#_camel_apache_org_v1_IntegrationProfileKameletSpec[IntegrationProfileKameletSpec]* +| + + +configuration to be executed to all Kamelets controlled by this IntegrationProfile + + +|=== + +[#_camel_apache_org_v1_IntegrationProfileStatus] +=== IntegrationProfileStatus + +*Appears on:* + +* <<#_camel_apache_org_v1_IntegrationProfile, IntegrationProfile>> + +IntegrationProfileStatus defines the observed state of IntegrationProfile. + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`IntegrationProfileSpec` + +*xref:#_camel_apache_org_v1_IntegrationProfileSpec[IntegrationProfileSpec]* +|(Members of `IntegrationProfileSpec` are embedded into this type.) + + + + +|`observedGeneration` + +int64 +| + + +ObservedGeneration is the most recent generation observed for this IntegrationProfile. + +|`phase` + +*xref:#_camel_apache_org_v1_IntegrationProfilePhase[IntegrationProfilePhase]* +| + + +defines in what phase the IntegrationProfile is found + +|`conditions` + +*xref:#_camel_apache_org_v1_IntegrationProfileCondition[[\]IntegrationProfileCondition]* +| + + +which are the conditions met (particularly useful when in ERROR phase) + + |=== [#_camel_apache_org_v1_IntegrationSpec] @@ -3706,6 +3997,7 @@ the default value of the property (if any) *Appears on:* * <<#_camel_apache_org_v1_IntegrationPlatformKameletSpec, IntegrationPlatformKameletSpec>> +* <<#_camel_apache_org_v1_IntegrationProfileKameletSpec, IntegrationProfileKameletSpec>> KameletRepositorySpec defines the location of the Kamelet catalog to use. @@ -4022,6 +4314,7 @@ Servers (auth) *Appears on:* * <<#_camel_apache_org_v1_IntegrationPlatformBuildSpec, IntegrationPlatformBuildSpec>> +* <<#_camel_apache_org_v1_IntegrationProfileBuildSpec, IntegrationProfileBuildSpec>> * <<#_camel_apache_org_v1_MavenBuildSpec, MavenBuildSpec>> MavenSpec --. @@ -4751,6 +5044,7 @@ be used to delay JSON decoding or precompute a JSON encoding. *Appears on:* * <<#_camel_apache_org_v1_IntegrationPlatformBuildSpec, IntegrationPlatformBuildSpec>> +* <<#_camel_apache_org_v1_IntegrationProfileBuildSpec, IntegrationProfileBuildSpec>> * <<#_camel_apache_org_v1_PublishTask, PublishTask>> RegistrySpec provides the configuration for the container registry. @@ -4904,6 +5198,7 @@ ResourceCondition is a common type for all conditions. * <<#_camel_apache_org_v1_IntegrationKitStatus, IntegrationKitStatus>> * <<#_camel_apache_org_v1_IntegrationPlatformBuildSpec, IntegrationPlatformBuildSpec>> +* <<#_camel_apache_org_v1_IntegrationProfileBuildSpec, IntegrationProfileBuildSpec>> * <<#_camel_apache_org_v1_IntegrationStatus, IntegrationStatus>> * <<#_camel_apache_org_v1_RuntimeSpec, RuntimeSpec>> @@ -5369,6 +5664,7 @@ TraitConfiguration parameters configuration *Appears on:* * <<#_camel_apache_org_v1_IntegrationPlatformSpec, IntegrationPlatformSpec>> +* <<#_camel_apache_org_v1_IntegrationProfileSpec, IntegrationProfileSpec>> * <<#_camel_apache_org_v1_IntegrationSpec, IntegrationSpec>> * <<#_camel_apache_org_v1_IntegrationStatus, IntegrationStatus>> diff --git a/e2e/advanced/integration_profile_test.go b/e2e/advanced/integration_profile_test.go new file mode 100644 index 0000000000..b4475fb0f2 --- /dev/null +++ b/e2e/advanced/integration_profile_test.go @@ -0,0 +1,213 @@ +//go:build integration +// +build integration + +// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" + +/* +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 advanced + +import ( + "testing" + + "github.com/apache/camel-k/v2/pkg/util/defaults" + . "github.com/onsi/gomega" + + corev1 "k8s.io/api/core/v1" + + . "github.com/apache/camel-k/v2/e2e/support" + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" +) + +func TestIntegrationProfile(t *testing.T) { + WithNewTestNamespace(t, func(ns string) { + operatorID := "camel-k-integration-profile" + Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) + Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + integrationProfile := v1.NewIntegrationProfile(ns, "ipr-global") + integrationProfile.SetOperatorID(operatorID) + integrationProfile.Spec.Traits.Container = &traitv1.ContainerTrait{ + Name: "ck-integration-global", + LimitCPU: "0.2", + } + + Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) + Eventually(SelectedIntegrationProfilePhase(ns, "ipr-global"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + + WithNewTestNamespace(t, func(ns1 string) { + integrationProfile := v1.NewIntegrationProfile(ns1, "ipr-local") + integrationProfile.SetOperatorID(operatorID) + integrationProfile.Spec.Traits.Container = &traitv1.ContainerTrait{ + LimitCPU: "0.1", + } + Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) + Eventually(SelectedIntegrationProfilePhase(ns1, "ipr-local"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + + t.Run("Run integration with global integration profile", func(t *testing.T) { + Expect(KamelRunWithID(operatorID, ns1, "--name", "limited", "--integration-profile", "ipr-global", "files/yaml.yaml").Execute()).To(Succeed()) + + Eventually(IntegrationPod(ns1, "limited"), TestTimeoutMedium).Should(Not(BeNil())) + Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + containerName := pod.Spec.Containers[0].Name + return containerName == "ck-integration-global" + }), TestTimeoutShort).Should(BeTrue()) + Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu() + return cpuLimits != nil && cpuLimits.AsApproximateFloat64() > 0 + }), TestTimeoutShort).Should(BeTrue()) + Expect(Kamel("delete", "limited", "-n", ns1).Execute()).To(Succeed()) + }) + + t.Run("Run integration with namespace local integration profile", func(t *testing.T) { + Expect(KamelRunWithID(operatorID, ns1, "--name", "limited", "--integration-profile", "ipr-local", "files/yaml.yaml").Execute()).To(Succeed()) + + Eventually(IntegrationPod(ns1, "limited"), TestTimeoutMedium).Should(Not(BeNil())) + Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + containerName := pod.Spec.Containers[0].Name + return containerName == "integration" + }), TestTimeoutShort).Should(BeTrue()) + + Eventually(IntegrationPodHas(ns1, "limited", func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu() + return cpuLimits != nil && cpuLimits.AsApproximateFloat64() > 0 + }), TestTimeoutShort).Should(BeTrue()) + Expect(Kamel("delete", "limited", "-n", ns1).Execute()).To(Succeed()) + }) + + t.Run("Run integration without integration profile", func(t *testing.T) { + Expect(KamelRunWithID(operatorID, ns1, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed()) + Eventually(IntegrationPod(ns1, "normal"), TestTimeoutShort).Should(Not(BeNil())) + Eventually(IntegrationPodHas(ns1, "normal", func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu() + return cpuLimits == nil || cpuLimits.IsZero() + }), TestTimeoutShort).Should(BeTrue()) + }) + + // Clean up + Expect(Kamel("delete", "--all", "-n", ns1).Execute()).To(Succeed()) + }) + }) +} + +func TestIntegrationProfileInfluencesKit(t *testing.T) { + WithNewTestNamespace(t, func(ns string) { + operatorID := "camel-k-ipr-kit" + Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) + Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + integrationProfile := v1.NewIntegrationProfile(ns, "ipr-global") + integrationProfile.SetOperatorID(operatorID) + integrationProfile.Spec.Traits.Builder = &traitv1.BuilderTrait{ + Properties: []string{"b1=foo"}, + } + + Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) + Eventually(SelectedIntegrationProfilePhase(ns, "ipr-global"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + + Expect(KamelRunWithID(operatorID, ns, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed()) + Eventually(IntegrationPod(ns, "normal"), TestTimeoutMedium).Should(Not(BeNil())) + Eventually(IntegrationPodPhase(ns, "normal"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + Eventually(IntegrationConditionStatus(ns, "normal", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + Eventually(IntegrationLogs(ns, "normal"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + // Verify that a new kit has been built based on the default base image + integrationKitName := IntegrationKit(ns, "normal")() + Eventually(Kit(ns, integrationKitName)().Status.BaseImage).Should(Equal(defaults.BaseImage())) + Eventually(Kit(ns, integrationKitName)().Status.RootImage).Should(Equal(defaults.BaseImage())) + + Expect(KamelRunWithID(operatorID, ns, "--name", "simple", "--integration-profile", "ipr-global", "files/yaml.yaml").Execute()).To(Succeed()) + + Eventually(IntegrationPod(ns, "simple"), TestTimeoutMedium).Should(Not(BeNil())) + Eventually(IntegrationPodPhase(ns, "simple"), TestTimeoutLong).Should(Equal(corev1.PodRunning)) + Eventually(IntegrationConditionStatus(ns, "simple", v1.IntegrationConditionReady), TestTimeoutShort).Should(Equal(corev1.ConditionTrue)) + Eventually(IntegrationLogs(ns, "simple"), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) + + // Verify that a new kit has been built based on the previous kit + integrationKitNameWithProfile := IntegrationKit(ns, "simple")() + Eventually(integrationKitNameWithProfile).ShouldNot(Equal(integrationKitName)) + Eventually(Kit(ns, integrationKitNameWithProfile)().Status.BaseImage).Should(ContainSubstring(integrationKitName)) + Eventually(Kit(ns, integrationKitNameWithProfile)().Status.RootImage).Should(Equal(defaults.BaseImage())) + + // Clean up + Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) +} + +func TestPropagateIntegrationProfileChanges(t *testing.T) { + WithNewTestNamespace(t, func(ns string) { + operatorID := "camel-k-ipr-changes" + Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) + Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + + integrationProfile := v1.NewIntegrationProfile(ns, "debug-profile") + integrationProfile.SetOperatorID(operatorID) + integrationProfile.Spec.Traits.Container = &traitv1.ContainerTrait{ + Name: "ck-ipr", + } + integrationProfile.Spec.Traits.Logging = &traitv1.LoggingTrait{ + Level: "DEBUG", + } + + Expect(CreateIntegrationProfile(&integrationProfile)).To(Succeed()) + Eventually(SelectedIntegrationProfilePhase(ns, "debug-profile"), TestTimeoutMedium).Should(Equal(v1.IntegrationProfilePhaseReady)) + + Expect(KamelRunWithID(operatorID, ns, "--name", "simple", "--integration-profile", "debug-profile", "files/yaml.yaml").Execute()).To(Succeed()) + + Eventually(IntegrationPod(ns, "simple"), TestTimeoutMedium).Should(Not(BeNil())) + Eventually(IntegrationPodHas(ns, "simple", func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + containerName := pod.Spec.Containers[0].Name + return containerName == "ck-ipr" + }), TestTimeoutShort).Should(BeTrue()) + + Expect(UpdateIntegrationProfile(ns, func(ipr *v1.IntegrationProfile) { + ipr.Spec.Traits.Container = &traitv1.ContainerTrait{ + Name: "ck-ipr-new", + } + })).To(Succeed()) + + Eventually(IntegrationPodHas(ns, "simple", func(pod *corev1.Pod) bool { + if len(pod.Spec.Containers) != 1 { + return false + } + containerName := pod.Spec.Containers[0].Name + return containerName == "ck-ipr-new" + }), TestTimeoutShort).Should(BeTrue()) + + // Clean up + Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) + }) +} diff --git a/e2e/advanced/operator_id_filtering_test.go b/e2e/advanced/operator_id_filtering_test.go index f639a94880..5305722cac 100644 --- a/e2e/advanced/operator_id_filtering_test.go +++ b/e2e/advanced/operator_id_filtering_test.go @@ -36,9 +36,8 @@ import ( func TestOperatorIDCamelCatalogReconciliation(t *testing.T) { WithNewTestNamespace(t, func(ns string) { - operator1 := "operator-1" - Expect(CopyCamelCatalog(ns, operator1)).To(Succeed()) - Expect(KamelInstallWithID(operator1, ns, "--global", "--force").Execute()).To(Succeed()) + operatorID := fmt.Sprintf("camel-k-%s", ns) + Expect(KamelInstallWithID(operatorID, ns, "--global", "--force").Execute()).To(Succeed()) Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) Eventually(DefaultCamelCatalogPhase(ns), TestTimeoutMedium).Should(Equal(v1.CamelCatalogPhaseReady)) }) @@ -49,13 +48,14 @@ func TestOperatorIDFiltering(t *testing.T) { WithNewTestNamespace(t, func(ns string) { WithNewTestNamespace(t, func(nsop1 string) { - WithNewTestNamespace(t, func(nsop2 string) { - operator1 := "operator-1" - Expect(CopyCamelCatalog(ns, operator1)).To(Succeed()) - Expect(KamelInstallWithIDAndKameletCatalog(operator1, nsop1, "--global", "--force").Execute()).To(Succeed()) - Eventually(PlatformPhase(nsop1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + operator1 := "operator-1" + Expect(CopyCamelCatalog(nsop1, operator1)).To(Succeed()) + Expect(KamelInstallWithIDAndKameletCatalog(operator1, nsop1, "--global", "--force").Execute()).To(Succeed()) + Eventually(PlatformPhase(nsop1), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) + WithNewTestNamespace(t, func(nsop2 string) { operator2 := "operator-2" + Expect(CopyCamelCatalog(nsop2, operator2)).To(Succeed()) Expect(KamelInstallWithIDAndKameletCatalog(operator2, nsop2, "--global", "--force").Execute()).To(Succeed()) Eventually(PlatformPhase(nsop2), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) diff --git a/e2e/advanced/secondary_platform_test.go b/e2e/advanced/secondary_platform_test.go deleted file mode 100644 index 11388b490b..0000000000 --- a/e2e/advanced/secondary_platform_test.go +++ /dev/null @@ -1,77 +0,0 @@ -//go:build integration -// +build integration - -// To enable compilation of this file in Goland, go to "Settings -> Go -> Vendoring & Build Tags -> Custom Tags" and add "integration" - -/* -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 advanced - -import ( - "testing" - - . "github.com/onsi/gomega" - - corev1 "k8s.io/api/core/v1" - - . "github.com/apache/camel-k/v2/e2e/support" - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" - traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" -) - -func TestSecondaryPlatform(t *testing.T) { - WithNewTestNamespace(t, func(ns string) { - operatorID := "camel-k-platform-secondary" - Expect(CopyCamelCatalog(ns, operatorID)).To(Succeed()) - Expect(KamelInstallWithID(operatorID, ns).Execute()).To(Succeed()) - Eventually(PlatformPhase(ns), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - - Expect(ConfigureSecondaryPlatformWith(ns, func(p *v1.IntegrationPlatform) { - p.Name = "secondary" - p.Spec.Traits.Container = &traitv1.ContainerTrait{ - LimitCPU: "0.1", - } - })).To(Succeed()) - Eventually(SelectedPlatformPhase(ns, "secondary"), TestTimeoutMedium).Should(Equal(v1.IntegrationPlatformPhaseReady)) - - Expect(KamelRunWithID(operatorID, ns, "--name", "limited", "--annotation", "camel.apache.org/platform.id=secondary", "files/yaml.yaml").Execute()).To(Succeed()) - - Eventually(IntegrationPod(ns, "limited"), TestTimeoutMedium).Should(Not(BeNil())) - Eventually(IntegrationPodHas(ns, "limited", func(pod *corev1.Pod) bool { - if len(pod.Spec.Containers) != 1 { - return false - } - cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu() - return cpuLimits != nil && cpuLimits.AsApproximateFloat64() > 0 - }), TestTimeoutShort).Should(BeTrue()) - Expect(Kamel("delete", "limited", "-n", ns).Execute()).To(Succeed()) - - Expect(KamelRunWithID(operatorID, ns, "--name", "normal", "files/yaml.yaml").Execute()).To(Succeed()) - Eventually(IntegrationPod(ns, "normal"), TestTimeoutShort).Should(Not(BeNil())) - Eventually(IntegrationPodHas(ns, "normal", func(pod *corev1.Pod) bool { - if len(pod.Spec.Containers) != 1 { - return false - } - cpuLimits := pod.Spec.Containers[0].Resources.Limits.Cpu() - return cpuLimits == nil || cpuLimits.IsZero() - }), TestTimeoutShort).Should(BeTrue()) - - // Clean up - Expect(Kamel("delete", "--all", "-n", ns).Execute()).To(Succeed()) - }) -} diff --git a/e2e/install/upgrade/helm_upgrade_test.go b/e2e/install/upgrade/helm_upgrade_test.go index b458c9acaf..17287386d6 100644 --- a/e2e/install/upgrade/helm_upgrade_test.go +++ b/e2e/install/upgrade/helm_upgrade_test.go @@ -87,11 +87,24 @@ func TestHelmOperatorUpgrade(t *testing.T) { Eventually(IntegrationLogs(ns, name), TestTimeoutShort).Should(ContainSubstring("Magicstring!")) }) - // Upgrade CRDs with kustomize + // Delete CRDs with kustomize ExpectExecSucceed(t, exec.Command( "kubectl", - "replace", + "delete", + "--ignore-not-found", + "-f", + "../../../helm/camel-k/crds/", + "-n", + ns, + ), + ) + + // Re-Create CRDs with kustomize + ExpectExecSucceed(t, + exec.Command( + "kubectl", + "create", "-f", "../../../helm/camel-k/crds/", "-n", diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go index 9ff4310e70..7b66c21ba3 100644 --- a/e2e/support/test_support.go +++ b/e2e/support/test_support.go @@ -1914,21 +1914,7 @@ func Platform(ns string) func() *v1.IntegrationPlatform { return nil } if len(lst.Items) > 1 { - var pl *v1.IntegrationPlatform - for _, p := range lst.Items { - p := p - if platform.IsSecondary(&p) { - continue - } - if pl != nil { - failTest(fmt.Errorf("multiple primary integration platforms found in namespace %q", ns)) - } - pl = &p - } - if pl == nil { - failTest(fmt.Errorf("multiple integration platforms found in namespace %q but no one is primary", ns)) - } - return pl + failTest(fmt.Errorf("multiple integration platforms found in namespace %q", ns)) } return &lst.Items[0] } @@ -1967,6 +1953,21 @@ func CopyCamelCatalog(ns, operatorID string) error { return nil } +func IntegrationProfileByName(ns string, name string) func() *v1.IntegrationProfile { + return func() *v1.IntegrationProfile { + lst := v1.NewIntegrationProfileList() + if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(err) + } + for _, pc := range lst.Items { + if pc.Name == name { + return &pc + } + } + return nil + } +} + func CamelCatalog(ns, name string) func() *v1.CamelCatalog { return func() *v1.CamelCatalog { cat := v1.CamelCatalog{} @@ -1983,6 +1984,43 @@ func CamelCatalog(ns, name string) func() *v1.CamelCatalog { } } +func IntegrationProfile(ns string) func() *v1.IntegrationProfile { + return func() *v1.IntegrationProfile { + lst := v1.NewIntegrationProfileList() + if err := TestClient().List(TestContext, &lst, ctrl.InNamespace(ns)); err != nil { + failTest(err) + } + if len(lst.Items) == 0 { + return nil + } + if len(lst.Items) > 1 { + failTest(fmt.Errorf("multiple integration profiles found in namespace %q", ns)) + } + return &lst.Items[0] + } +} + +func CreateIntegrationProfile(profile *v1.IntegrationProfile) error { + return TestClient().Create(TestContext, profile) +} + +func UpdateIntegrationProfile(ns string, upd func(ipr *v1.IntegrationProfile)) error { + ipr := IntegrationProfile(ns)() + if ipr == nil { + return fmt.Errorf("unable to locate Integration Profile in %s", ns) + } + target := ipr.DeepCopy() + upd(target) + // For some reason, full patch fails on some clusters + p, err := patch.MergePatch(ipr, target) + if err != nil { + return err + } else if len(p) == 0 { + return nil + } + return TestClient().Patch(TestContext, target, ctrl.RawPatch(types.MergePatchType, p)) +} + func CreateCamelCatalog(catalog *v1.CamelCatalog) func() error { return func() error { return TestClient().Create(TestContext, catalog) @@ -2101,6 +2139,16 @@ func SelectedPlatformPhase(ns string, name string) func() v1.IntegrationPlatform } } +func SelectedIntegrationProfilePhase(ns string, name string) func() v1.IntegrationProfilePhase { + return func() v1.IntegrationProfilePhase { + pc := IntegrationProfileByName(ns, name)() + if pc == nil { + return "" + } + return pc.Status.Phase + } +} + func PlatformHas(ns string, predicate func(pl *v1.IntegrationPlatform) bool) func() bool { return func() bool { pl := Platform(ns)() @@ -2167,20 +2215,6 @@ func AssignPlatformToOperator(ns, operator string) error { return TestClient().Update(TestContext, pl) } -func ConfigureSecondaryPlatformWith(ns string, customizer func(pl *v1.IntegrationPlatform)) error { - pl := Platform(ns)() - if pl == nil { - return errors.New("cannot find primary platform") - } - - v1.SetAnnotation(&pl.ObjectMeta, v1.SecondaryPlatformAnnotation, "true") - pl.ObjectMeta.ResourceVersion = "" - pl.Name = "" - pl.Status = v1.IntegrationPlatformStatus{} - customizer(pl) - return TestClient().Create(TestContext, pl) -} - func CRDs() func() []metav1.APIResource { return func() []metav1.APIResource { diff --git a/e2e/support/util/dump.go b/e2e/support/util/dump.go index c0a8661142..c170cf6aad 100644 --- a/e2e/support/util/dump.go +++ b/e2e/support/util/dump.go @@ -187,6 +187,21 @@ func Dump(ctx context.Context, c client.Client, ns string, t *testing.T) error { t.Logf("---\n%s\n---\n", string(pdata)) } + // IntegrationProfiles + iprs, err := camelClient.CamelV1().IntegrationProfiles(ns).List(ctx, metav1.ListOptions{}) + if err != nil { + return err + } + t.Logf("Found %d integration profiles:\n", len(iprs.Items)) + for _, p := range iprs.Items { + ref := p + pdata, err := kubernetes.ToYAMLNoManagedFields(&ref) + if err != nil { + return err + } + t.Logf("---\n%s\n---\n", string(pdata)) + } + // CamelCatalogs cats, err := camelClient.CamelV1().CamelCatalogs(ns).List(ctx, metav1.ListOptions{}) if err != nil { diff --git a/helm/camel-k/crds/crd-integration-profile.yaml b/helm/camel-k/crds/crd-integration-profile.yaml new file mode 100644 index 0000000000..3e997b3cea --- /dev/null +++ b/helm/camel-k/crds/crd-integration-profile.yaml @@ -0,0 +1,3559 @@ +# --------------------------------------------------------------------------- +# 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: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + labels: + app: camel-k + name: integrationprofiles.camel.apache.org +spec: + group: camel.apache.org + names: + categories: + - kamel + - camel + kind: IntegrationProfile + listKind: IntegrationProfileList + plural: integrationprofiles + shortNames: + - ipr + singular: integrationprofile + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The integration profile phase + jsonPath: .status.phase + name: Phase + type: string + - description: The default runtime version + jsonPath: .status.build.runtimeVersion + name: Default runtime + type: string + name: v1 + schema: + openAPIV3Schema: + description: IntegrationProfile is the resource used to apply user defined + settings to the Camel K operator behavior. It defines the behavior of all + Custom Resources (`IntegrationKit`, `Integration`, `Kamelet`) in the given + namespace. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: IntegrationProfileSpec applies user defined settings to the + IntegrationProfile. + properties: + build: + description: specify how to build the Integration/IntegrationKits + properties: + baseImage: + description: a base image that can be used as base layer for all + images. It can be useful if you want to provide some custom + base image with further utility software + type: string + maven: + description: Maven configuration used to build the Camel/Camel-Quarkus + applications + properties: + caSecrets: + description: The Secrets name and key, containing the CA certificate(s) + used to connect to remote Maven repositories. It can contain + X.509 certificates, and PKCS#7 formatted certificate chains. + A JKS formatted keystore is automatically created to store + the CA certificate(s), and configured to be used as a trusted + certificate(s) by the Maven commands. Note that the root + CA certificates are also imported into the created keystore. + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: array + cliOptions: + description: The CLI options that are appended to the list + of arguments for Maven commands, e.g., `-V,--no-transfer-progress,-Dstyle.color=never`. + See https://maven.apache.org/ref/3.8.4/maven-embedder/cli.html. + items: + type: string + type: array + extension: + description: The Maven build extensions. See https://maven.apache.org/guides/mini/guide-using-extensions.html. + items: + description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) + Maven artifact. + properties: + artifactId: + description: Maven Artifact + type: string + classifier: + description: Maven Classifier + type: string + groupId: + description: Maven Group + type: string + type: + description: Maven Type + type: string + version: + description: Maven Version + type: string + required: + - artifactId + - groupId + type: object + type: array + localRepository: + description: The path of the local Maven repository. + type: string + profiles: + description: A reference to the ConfigMap or Secret key that + contains the Maven profile. + items: + description: ValueSource --. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: array + properties: + additionalProperties: + type: string + description: The Maven properties. + type: object + settings: + description: A reference to the ConfigMap or Secret key that + contains the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + settingsSecurity: + description: A reference to the ConfigMap or Secret key that + contains the security of the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: object + registry: + description: the image registry used to push/pull Integration + images + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate Authority + type: string + insecure: + description: if the container registry is insecure (ie, http + only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + runtimeProvider: + description: the runtime used. Likely Camel Quarkus (we used to + have main runtime which has been discontinued since version + 1.5) + type: string + runtimeVersion: + description: the Camel K Runtime dependency version + type: string + timeout: + description: how much time to wait before time out the pipeline + process + type: string + type: object + kamelet: + description: configuration to be executed to all Kamelets controlled + by this IntegrationProfile + properties: + repositories: + description: remote repository used to retrieve Kamelet catalog + items: + description: KameletRepositorySpec defines the location of the + Kamelet catalog to use. + properties: + uri: + description: the remote repository in the format github:ORG/REPO/PATH_TO_KAMELETS_FOLDER + type: string + type: object + type: array + type: object + traits: + description: list of traits to be executed for all the Integration/IntegrationKits + built from this IntegrationProfile + properties: + 3scale: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + addons: + additionalProperties: + description: AddonTrait represents the configuration of an addon + trait. + type: object + x-kubernetes-preserve-unknown-fields: true + description: The extension point with addon traits + type: object + affinity: + description: The configuration of Affinity trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodeAffinityLabels: + description: Defines a set of nodes the integration pod(s) + are eligible to be scheduled on, based on labels on the + node. + items: + type: string + type: array + podAffinity: + description: Always co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should be co-located with. + items: + type: string + type: array + podAntiAffinity: + description: Never co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAntiAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should not be co-located with. + items: + type: string + type: array + type: object + builder: + description: The configuration of Builder trait + properties: + annotations: + additionalProperties: + type: string + description: When using `pod` strategy, annotation to use + for the builder pod. + type: object + baseImage: + description: Specify a base image + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + incrementalImageBuild: + description: Use the incremental image build option, to reuse + existing containers (default `true`) + type: boolean + limitCPU: + description: 'When using `pod` strategy, the maximum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + limitMemory: + description: 'When using `pod` strategy, the maximum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + mavenProfiles: + description: 'A list of references pointing to configmaps/secrets + that contains a maven profile. The content of the maven + profile is expected to be a text containing a valid maven + profile starting with `` and ending with `` + that will be integrated as an inline profile in the POM. + Syntax: [configmap|secret]:name[/key], where name represents + the resource name, key optionally represents the resource + key to be filtered (default key value = profile.xml).' + items: + type: string + type: array + nodeSelector: + additionalProperties: + type: string + description: Defines a set of nodes the builder pod is eligible + to be scheduled on, based on labels on the node. + type: object + orderStrategy: + description: The build order strategy to use, either `dependencies`, + `fifo` or `sequential` (default `sequential`) + enum: + - dependencies + - fifo + - sequential + type: string + properties: + description: A list of properties to be provided to the build + task + items: + type: string + type: array + requestCPU: + description: 'When using `pod` strategy, the minimum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + requestMemory: + description: 'When using `pod` strategy, the minimum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + strategy: + description: The strategy to use, either `pod` or `routine` + (default `routine`) + enum: + - pod + - routine + type: string + tasks: + description: A list of tasks to be executed (available only + when using `pod` strategy) with format `;;`. + items: + type: string + type: array + tasksFilter: + description: A list of tasks sorted by the order of execution + in a csv format, ie, `,,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only with `pod` strategy. + type: string + tasksLimitCPU: + description: A list of limit cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksLimitMemory: + description: A list of limit memory configuration for the + specific task with format `:`. + items: + type: string + type: array + tasksRequestCPU: + description: A list of request cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksRequestMemory: + description: A list of request memory configuration for the + specific task with format `:`. + items: + type: string + type: array + verbose: + description: Enable verbose logging on build components that + support it (e.g. Kaniko build pod). Deprecated no longer + in use + type: boolean + type: object + camel: + description: The configuration of Camel trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + properties: + description: A list of properties to be provided to the Integration + runtime + items: + type: string + type: array + runtimeVersion: + description: The camel-k-runtime version to use for the integration. + It overrides the default version set in the Integration + Platform. + type: string + type: object + container: + description: The configuration of Container trait + properties: + auto: + description: To automatically enable the trait + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + expose: + description: Can be used to enable/disable exposure via kubernetes + Service. + type: boolean + image: + description: The main container image + type: string + imagePullPolicy: + description: 'The pull policy: Always|Never|IfNotPresent' + enum: + - Always + - Never + - IfNotPresent + type: string + limitCPU: + description: The maximum amount of CPU required. + type: string + limitMemory: + description: The maximum amount of memory required. + type: string + name: + description: The main container name. It's named `integration` + by default. + type: string + port: + description: To configure a different port exposed by the + container (default `8080`). + type: integer + portName: + description: To configure a different port name for the port + exposed by the container. It defaults to `http` only when + the `expose` parameter is true. + type: string + requestCPU: + description: The minimum amount of CPU required. + type: string + requestMemory: + description: The minimum amount of memory required. + type: string + servicePort: + description: To configure under which service port the container + port is to be exposed (default `80`). + type: integer + servicePortName: + description: To configure under which service port name the + container port is to be exposed (default `http`). + type: string + type: object + cron: + description: The configuration of Cron trait + properties: + activeDeadlineSeconds: + description: Specifies the duration in seconds, relative to + the start time, that the job may be continuously active + before it is considered to be failed. It defaults to 60s. + format: int64 + type: integer + auto: + description: "Automatically deploy the integration as CronJob + when all routes are either starting from a periodic consumer + (only `cron`, `timer` and `quartz` are supported) or a passive + consumer (e.g. `direct` is a passive consumer). \n It's + required that all periodic consumers have the same period, + and it can be expressed as cron schedule (e.g. `1m` can + be expressed as `0/1 * * * *`, while `35m` or `50s` cannot)." + type: boolean + backoffLimit: + description: Specifies the number of retries before marking + the job failed. It defaults to 2. + format: int32 + type: integer + components: + description: "A comma separated list of the Camel components + that need to be customized in order for them to work when + the schedule is triggered externally by Kubernetes. A specific + customizer is activated for each specified component. E.g. + for the `timer` component, the `cron-timer` customizer is + activated (it's present in the `org.apache.camel.k:camel-k-cron` + library). \n Supported components are currently: `cron`, + `timer` and `quartz`." + type: string + concurrencyPolicy: + description: 'Specifies how to treat concurrent executions + of a Job. Valid values are: - "Allow": allows CronJobs to + run concurrently; - "Forbid" (default): forbids concurrent + runs, skipping next run if previous run hasn''t finished + yet; - "Replace": cancels currently running job and replaces + it with a new one' + enum: + - Allow + - Forbid + - Replace + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + fallback: + description: Use the default Camel implementation of the `cron` + endpoint (`quartz`) instead of trying to materialize the + integration as Kubernetes CronJob. + type: boolean + schedule: + description: The CronJob schedule for the whole integration. + If multiple routes are declared, they must have the same + schedule for this mechanism to work correctly. + type: string + startingDeadlineSeconds: + description: Optional deadline in seconds for starting the + job if it misses scheduled time for any reason. Missed + jobs executions will be counted as failed ones. + format: int64 + type: integer + type: object + dependencies: + description: The configuration of Dependencies trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + deployer: + description: The configuration of Deployer trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + kind: + description: Allows to explicitly select the desired deployment + kind between `deployment`, `cron-job` or `knative-service` + when creating the resources for running the integration. + enum: + - deployment + - cron-job + - knative-service + type: string + useSSA: + description: Use server-side apply to update the owned resources + (default `true`). Note that it automatically falls back + to client-side patching, if SSA is not available, e.g., + on old Kubernetes clusters. + type: boolean + type: object + deployment: + description: The configuration of Deployment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + progressDeadlineSeconds: + description: The maximum time in seconds for the deployment + to make progress before it is considered to be failed. It + defaults to `60s`. + format: int32 + type: integer + rollingUpdateMaxSurge: + description: 'The maximum number of pods that can be scheduled + above the desired number of pods. Value can be an absolute + number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. Absolute number + is calculated from percentage by rounding up. Defaults to + `25%`.' + type: integer + rollingUpdateMaxUnavailable: + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute number + is calculated from percentage by rounding down. This can + not be 0 if MaxSurge is 0. Defaults to `25%`.' + type: integer + strategy: + description: The deployment strategy to use to replace existing + pods with new ones. + enum: + - Recreate + - RollingUpdate + type: string + type: object + environment: + description: The configuration of Environment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + containerMeta: + description: Enables injection of `NAMESPACE` and `POD_NAME` + environment variables (default `true`) + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + httpProxy: + description: Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and + `NO_PROXY` environment variables (default `true`) + type: boolean + vars: + description: A list of environment variables to be added to + the integration container. The syntax is KEY=VALUE, e.g., + `MY_VAR="my value"`. These take precedence over the previously + defined environment variables. + items: + type: string + type: array + type: object + error-handler: + description: The configuration of Error Handler trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + ref: + description: The error handler ref name provided or found + in application properties + type: string + type: object + gc: + description: The configuration of GC trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryCache: + description: 'Discovery client cache to be used, either `disabled`, + `disk` or `memory` (default `memory`). Deprecated: to be + removed from trait configuration.' + enum: + - disabled + - disk + - memory + type: string + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + health: + description: The configuration of Health trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + livenessFailureThreshold: + description: Minimum consecutive failures for the liveness + probe to be considered failed after having succeeded. + format: int32 + type: integer + livenessInitialDelay: + description: Number of seconds after the container has started + before the liveness probe is initiated. + format: int32 + type: integer + livenessPeriod: + description: How often to perform the liveness probe. + format: int32 + type: integer + livenessProbeEnabled: + description: Configures the liveness probe for the integration + container (default `false`). + type: boolean + livenessScheme: + description: Scheme to use when connecting to the liveness + probe (default `HTTP`). + type: string + livenessSuccessThreshold: + description: Minimum consecutive successes for the liveness + probe to be considered successful after having failed. + format: int32 + type: integer + livenessTimeout: + description: Number of seconds after which the liveness probe + times out. + format: int32 + type: integer + readinessFailureThreshold: + description: Minimum consecutive failures for the readiness + probe to be considered failed after having succeeded. + format: int32 + type: integer + readinessInitialDelay: + description: Number of seconds after the container has started + before the readiness probe is initiated. + format: int32 + type: integer + readinessPeriod: + description: How often to perform the readiness probe. + format: int32 + type: integer + readinessProbeEnabled: + description: Configures the readiness probe for the integration + container (default `true`). + type: boolean + readinessScheme: + description: Scheme to use when connecting to the readiness + probe (default `HTTP`). + type: string + readinessSuccessThreshold: + description: Minimum consecutive successes for the readiness + probe to be considered successful after having failed. + format: int32 + type: integer + readinessTimeout: + description: Number of seconds after which the readiness probe + times out. + format: int32 + type: integer + startupFailureThreshold: + description: Minimum consecutive failures for the startup + probe to be considered failed after having succeeded. + format: int32 + type: integer + startupInitialDelay: + description: Number of seconds after the container has started + before the startup probe is initiated. + format: int32 + type: integer + startupPeriod: + description: How often to perform the startup probe. + format: int32 + type: integer + startupProbeEnabled: + description: Configures the startup probe for the integration + container (default `false`). + type: boolean + startupScheme: + description: Scheme to use when connecting to the startup + probe (default `HTTP`). + type: string + startupSuccessThreshold: + description: Minimum consecutive successes for the startup + probe to be considered successful after having failed. + format: int32 + type: integer + startupTimeout: + description: Number of seconds after which the startup probe + times out. + format: int32 + type: integer + type: object + ingress: + description: The configuration of Ingress trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to the ingress. This can + be used to set controller specific annotations, e.g., when + using the NGINX Ingress controller: See https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md' + type: object + auto: + description: To automatically add an ingress whenever the + integration uses an HTTP endpoint consumer. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the ingress. + type: string + path: + description: To configure the path exposed by the ingress + (default `/`). + type: string + pathType: + description: To configure the path type exposed by the ingress. + One of `Exact`, `Prefix`, `ImplementationSpecific` (default + to `Prefix`). + enum: + - Exact + - Prefix + - ImplementationSpecific + type: string + type: object + istio: + description: The configuration of Istio trait + properties: + allow: + description: Configures a (comma-separated) list of CIDR subnets + that should not be intercepted by the Istio proxy (`10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` + by default). + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + inject: + description: Forces the value for labels `sidecar.istio.io/inject`. + By default the label is set to `true` on deployment and + not set on Knative Service. + type: boolean + type: object + jolokia: + description: The configuration of Jolokia trait + properties: + CACert: + description: The PEM encoded CA certification file path, used + to verify client certificates, applicable when `protocol` + is `https` and `use-ssl-client-authentication` is `true` + (default `/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt` + for OpenShift). + type: string + clientPrincipal: + description: The principal(s) which must be given in a client + certificate to allow access to the Jolokia endpoint, applicable + when `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `clientPrincipal=cn=system:master-proxy`, + `cn=hawtio-online.hawtio.svc` and `cn=fuse-console.fuse.svc` + for OpenShift). + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryEnabled: + description: Listen for multicast requests (default `false`) + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + extendedClientCheck: + description: Mandate the client certificate contains a client + flag in the extended key usage section, applicable when + `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `true` for OpenShift). + type: boolean + host: + description: The Host address to which the Jolokia agent should + bind to. If `"\*"` or `"0.0.0.0"` is given, the servers + binds to every network interface (default `"*"`). + type: string + options: + description: A list of additional Jolokia options as defined + in https://jolokia.org/reference/html/agents.html#agent-jvm-config[JVM + agent configuration options] + items: + type: string + type: array + password: + description: The password used for authentication, applicable + when the `user` option is set. + type: string + port: + description: The Jolokia endpoint port (default `8778`). + type: integer + protocol: + description: The protocol to use, either `http` or `https` + (default `https` for OpenShift) + type: string + useSSLClientAuthentication: + description: Whether client certificates should be used for + authentication (default `true` for OpenShift). + type: boolean + user: + description: The user to be used for authentication + type: string + type: object + jvm: + description: The configuration of JVM trait + properties: + classpath: + description: Additional JVM classpath (use `Linux` classpath + separator) + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + debug: + description: Activates remote debugging, so that a debugger + can be attached to the JVM, e.g., using port-forwarding + type: boolean + debugAddress: + description: Transport address at which to listen for the + newly launched JVM (default `*:5005`) + type: string + debugSuspend: + description: Suspends the target JVM immediately before the + main class is loaded + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + options: + description: A list of JVM options + items: + type: string + type: array + printCommand: + description: Prints the command used the start the JVM in + the container logs (default `true`) + type: boolean + type: object + kamelets: + description: The configuration of Kamelets trait + properties: + auto: + description: Automatically inject all referenced Kamelets + and their default configuration (enabled by default) + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + list: + description: Comma separated list of Kamelet names to load + into the current integration + type: string + mountPoint: + description: The directory where the application mounts and + reads Kamelet spec (default `/etc/camel/kamelets`) + type: string + type: object + keda: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + knative: + description: The configuration of Knative trait + properties: + auto: + description: Enable automatic discovery of all trait properties. + type: boolean + channelSinks: + description: List of channels used as destination of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + channelSources: + description: List of channels used as source of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + config: + description: Can be used to inject a Knative complete configuration + in JSON format. + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + endpointSinks: + description: List of endpoints used as destination of integration + routes. Can contain simple endpoint names or full Camel + URIs. + items: + type: string + type: array + endpointSources: + description: List of channels used as source of integration + routes. + items: + type: string + type: array + eventSinks: + description: List of event types that the integration will + produce. Can contain simple event types or full Camel URIs + (to use a specific broker). + items: + type: string + type: array + eventSources: + description: List of event types that the integration will + be subscribed to. Can contain simple event types or full + Camel URIs (to use a specific broker different from "default"). + items: + type: string + type: array + filterSourceChannels: + description: Enables filtering on events based on the header + "ce-knativehistory". Since this header has been removed + in newer versions of Knative, filtering is disabled by default. + type: boolean + namespaceLabel: + description: 'Enables the camel-k-operator to set the "bindings.knative.dev/include=true" + label to the namespace As Knative requires this label to + perform injection of K_SINK URL into the service. If this + is false, the integration pod may start and fail, read the + SinkBinding Knative documentation. (default: true)' + type: boolean + sinkBinding: + description: Allows binding the integration to a sink via + a Knative SinkBinding resource. This can be used when the + integration targets a single sink. It's enabled by default + when the integration targets a single sink (except when + the integration is owned by a Knative source). + type: boolean + type: object + knative-service: + description: The configuration of Knative Service trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set knative service specific annotations CLI usage + example: -t "knative-service.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + auto: + description: "Automatically deploy the integration as Knative + service when all conditions hold: \n * Integration is using + the Knative profile * All routes are either starting from + an HTTP based consumer or a passive consumer (e.g. `direct` + is a passive consumer)" + type: boolean + autoscalingMetric: + description: "Configures the Knative autoscaling metric property + (e.g. to set `concurrency` based or `cpu` based autoscaling). + \n Refer to the Knative documentation for more information." + type: string + autoscalingTarget: + description: "Sets the allowed concurrency level or CPU percentage + (depending on the autoscaling metric) for each Pod. \n Refer + to the Knative documentation for more information." + type: integer + class: + description: "Configures the Knative autoscaling class property + (e.g. to set `hpa.autoscaling.knative.dev` or `kpa.autoscaling.knative.dev` + autoscaling). \n Refer to the Knative documentation for + more information." + enum: + - kpa.autoscaling.knative.dev + - hpa.autoscaling.knative.dev + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxScale: + description: "An upper bound for the number of Pods that can + be running in parallel for the integration. Knative has + its own cap value that depends on the installation. \n Refer + to the Knative documentation for more information." + type: integer + minScale: + description: "The minimum number of Pods that should be running + at any time for the integration. It's **zero** by default, + meaning that the integration is scaled down to zero when + not used for a configured amount of time. \n Refer to the + Knative documentation for more information." + type: integer + rolloutDuration: + description: Enables to gradually shift traffic to the latest + Revision and sets the rollout duration. It's disabled by + default and must be expressed as a Golang `time.Duration` + string representation, rounded to a second precision. + type: string + visibility: + description: "Setting `cluster-local`, Knative service becomes + a private service. Specifically, this option applies the + `networking.knative.dev/visibility` label to Knative service. + \n Refer to the Knative documentation for more information." + enum: + - cluster-local + type: string + type: object + logging: + description: The configuration of Logging trait + properties: + color: + description: Colorize the log output + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + format: + description: Logs message format + type: string + json: + description: Output the logs in JSON + type: boolean + jsonPrettyPrint: + description: Enable "pretty printing" of the JSON logs + type: boolean + level: + description: Adjust the logging level (defaults to `INFO`) + enum: + - FATAL + - WARN + - INFO + - DEBUG + - TRACE + type: string + type: object + master: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + mount: + description: The configuration of Mount trait + properties: + configs: + description: 'A list of configuration pointing to configmap/secret. + The configuration are expected to be UTF-8 resources as + they are processed by runtime Camel Context and tried to + be parsed as property files. They are also made available + on the classpath in order to ease their usage directly from + the Route. Syntax: [configmap|secret]:name[/key], where + name represents the resource name and key optionally represents + the resource key to be filtered' + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + hotReload: + description: Enable "hot reload" when a secret/configmap mounted + is edited (default `false`). The configmap/secret must be + marked with `camel.apache.org/integration` label to be taken + in account. + type: boolean + resources: + description: 'A list of resources (text or binary content) + pointing to configmap/secret. The resources are expected + to be any resource type (text or binary content). The destination + path can be either a default location or any path specified + by the user. Syntax: [configmap|secret]:name[/key][@path], + where name represents the resource name, key optionally + represents the resource key to be filtered and path represents + the destination path' + items: + type: string + type: array + volumes: + description: 'A list of Persistent Volume Claims to be mounted. + Syntax: [pvcname:/container/path]' + items: + type: string + type: array + type: object + openapi: + description: The configuration of OpenAPI trait + properties: + configmaps: + description: The configmaps holding the spec of the OpenAPI + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + owner: + description: The configuration of Owner trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + targetAnnotations: + description: The set of annotations to be transferred + items: + type: string + type: array + targetLabels: + description: The set of labels to be transferred + items: + type: string + type: array + type: object + pdb: + description: The configuration of PDB trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxUnavailable: + description: The number of pods for the Integration that can + be unavailable after an eviction. It can be either an absolute + number or a percentage (default `1` if `min-available` is + also not set). Only one of `max-unavailable` and `min-available` + can be specified. + type: string + minAvailable: + description: The number of pods for the Integration that must + still be available after an eviction. It can be either an + absolute number or a percentage. Only one of `min-available` + and `max-unavailable` can be specified. + type: string + type: object + platform: + description: The configuration of Platform trait + properties: + auto: + description: 'To automatically detect from the environment + if a default platform can be created (it will be created + on OpenShift or when a registry address is set). Deprecated: + Platform is auto generated by the operator install procedure + - maintained for backward compatibility' + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + createDefault: + description: 'To create a default (empty) platform when the + platform is missing. Deprecated: Platform is auto generated + by the operator install procedure - maintained for backward + compatibility' + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + global: + description: 'Indicates if the platform should be created + globally in the case of global operator (default true). + Deprecated: Platform is auto generated by the operator install + procedure - maintained for backward compatibility' + type: boolean + type: object + pod: + description: The configuration of Pod trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + prometheus: + description: The configuration of Prometheus trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + podMonitor: + description: Whether a `PodMonitor` resource is created (default + `true`). + type: boolean + podMonitorLabels: + description: The `PodMonitor` resource labels, applicable + when `pod-monitor` is `true`. + items: + type: string + type: array + type: object + pull-secret: + description: The configuration of Pull Secret trait + properties: + auto: + description: Automatically configures the platform registry + secret on the pod if it is of type `kubernetes.io/dockerconfigjson`. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + imagePullerDelegation: + description: When using a global operator with a shared platform, + this enables delegation of the `system:image-puller` cluster + role on the operator namespace to the integration service + account. + type: boolean + secretName: + description: The pull secret name to set on the Pod. If left + empty this is automatically taken from the `IntegrationPlatform` + registry configuration. + type: string + type: object + quarkus: + description: The configuration of Quarkus trait + properties: + buildMode: + description: 'The Quarkus mode to run: either `jvm` or `native` + (default `jvm`). In case both `jvm` and `native` are specified, + two `IntegrationKit` resources are created, with the `native` + kit having precedence over the `jvm` one once ready.' + items: + description: QuarkusMode is the type of Quarkus build packaging. + enum: + - jvm + - native + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + nativeBaseImage: + description: The base image to use when running a native build + (default `quay.io/quarkus/quarkus-micro-image:2.0`) + type: string + nativeBuilderImage: + description: The image containing the tooling required for + a native build (by default it will use the one provided + in the runtime catalog) + type: string + packageTypes: + description: 'The Quarkus package types, `fast-jar` or `native` + (default `fast-jar`). In case both `fast-jar` and `native` + are specified, two `IntegrationKit` resources are created, + with the native kit having precedence over the `fast-jar` + one once ready. The order influences the resolution of the + current kit for the integration. The kit corresponding to + the first package type will be assigned to the integration + in case no existing kit that matches the integration exists. + Deprecated: use `build-mode` instead.' + items: + description: 'QuarkusPackageType is the type of Quarkus + build packaging. Deprecated: use `QuarkusMode` instead.' + enum: + - fast-jar + - native + type: string + type: array + type: object + registry: + description: The configuration of Registry trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + route: + description: The configuration of Route trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set route specific annotations For annotations options + see https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#route-specific-annotations + CLI usage example: -t "route.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the route. + type: string + tlsCACertificate: + description: "The TLS CA certificate contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsCACertificateSecret: + description: "The secret name and key reference to the TLS + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsCertificate: + description: "The TLS certificate contents. \n Refer to the + OpenShift route documentation for additional information." + type: string + tlsCertificateSecret: + description: "The secret name and key reference to the TLS + certificate. The format is \"secret-name[/key-name]\", the + value represents the secret name, if there is only one key + in the secret it will be read, otherwise you can set a key + name separated with a \"/\". \n Refer to the OpenShift route + documentation for additional information." + type: string + tlsDestinationCACertificate: + description: "The destination CA certificate provides the + contents of the ca certificate of the final destination. + \ When using reencrypt termination this file should be provided + in order to have routers use it for health checks on the + secure connection. If this field is not specified, the router + may provide its own destination CA and perform hostname + validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to automatically + verify. \n Refer to the OpenShift route documentation for + additional information." + type: string + tlsDestinationCACertificateSecret: + description: "The secret name and key reference to the destination + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsInsecureEdgeTerminationPolicy: + description: "To configure how to deal with insecure traffic, + e.g. `Allow`, `Disable` or `Redirect` traffic. \n Refer + to the OpenShift route documentation for additional information." + enum: + - None + - Allow + - Redirect + type: string + tlsKey: + description: "The TLS certificate key contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsKeySecret: + description: "The secret name and key reference to the TLS + certificate key. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsTermination: + description: "The TLS termination type, like `edge`, `passthrough` + or `reencrypt`. \n Refer to the OpenShift route documentation + for additional information." + enum: + - edge + - reencrypt + - passthrough + type: string + type: object + service: + description: The configuration of Service trait + properties: + auto: + description: To automatically detect from the code if a Service + needs to be created. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodePort: + description: 'Enable Service to be exposed as NodePort (default + `false`). Deprecated: Use service type instead.' + type: boolean + type: + description: The type of service to be used, either 'ClusterIP', + 'NodePort' or 'LoadBalancer'. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + type: object + service-binding: + description: The configuration of Service Binding trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + services: + description: List of Services in the form [[apigroup/]version:]kind:[namespace/]name + items: + type: string + type: array + type: object + strimzi: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + toleration: + description: The configuration of Toleration trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + taints: + description: The list of taints to tolerate, in the form `Key[=Value]:Effect[:Seconds]` + items: + type: string + type: array + type: object + tracing: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + type: object + type: object + status: + description: IntegrationProfileStatus defines the observed state of IntegrationProfile. + properties: + build: + description: specify how to build the Integration/IntegrationKits + properties: + baseImage: + description: a base image that can be used as base layer for all + images. It can be useful if you want to provide some custom + base image with further utility software + type: string + maven: + description: Maven configuration used to build the Camel/Camel-Quarkus + applications + properties: + caSecrets: + description: The Secrets name and key, containing the CA certificate(s) + used to connect to remote Maven repositories. It can contain + X.509 certificates, and PKCS#7 formatted certificate chains. + A JKS formatted keystore is automatically created to store + the CA certificate(s), and configured to be used as a trusted + certificate(s) by the Maven commands. Note that the root + CA certificates are also imported into the created keystore. + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: array + cliOptions: + description: The CLI options that are appended to the list + of arguments for Maven commands, e.g., `-V,--no-transfer-progress,-Dstyle.color=never`. + See https://maven.apache.org/ref/3.8.4/maven-embedder/cli.html. + items: + type: string + type: array + extension: + description: The Maven build extensions. See https://maven.apache.org/guides/mini/guide-using-extensions.html. + items: + description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) + Maven artifact. + properties: + artifactId: + description: Maven Artifact + type: string + classifier: + description: Maven Classifier + type: string + groupId: + description: Maven Group + type: string + type: + description: Maven Type + type: string + version: + description: Maven Version + type: string + required: + - artifactId + - groupId + type: object + type: array + localRepository: + description: The path of the local Maven repository. + type: string + profiles: + description: A reference to the ConfigMap or Secret key that + contains the Maven profile. + items: + description: ValueSource --. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: array + properties: + additionalProperties: + type: string + description: The Maven properties. + type: object + settings: + description: A reference to the ConfigMap or Secret key that + contains the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + settingsSecurity: + description: A reference to the ConfigMap or Secret key that + contains the security of the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: object + registry: + description: the image registry used to push/pull Integration + images + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate Authority + type: string + insecure: + description: if the container registry is insecure (ie, http + only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + runtimeProvider: + description: the runtime used. Likely Camel Quarkus (we used to + have main runtime which has been discontinued since version + 1.5) + type: string + runtimeVersion: + description: the Camel K Runtime dependency version + type: string + timeout: + description: how much time to wait before time out the pipeline + process + type: string + type: object + conditions: + description: which are the conditions met (particularly useful when + in ERROR phase) + items: + description: IntegrationProfileCondition describes the state of + a resource at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human-readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of integration condition. + type: string + required: + - status + - type + type: object + type: array + kamelet: + description: configuration to be executed to all Kamelets controlled + by this IntegrationProfile + properties: + repositories: + description: remote repository used to retrieve Kamelet catalog + items: + description: KameletRepositorySpec defines the location of the + Kamelet catalog to use. + properties: + uri: + description: the remote repository in the format github:ORG/REPO/PATH_TO_KAMELETS_FOLDER + type: string + type: object + type: array + type: object + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this IntegrationProfile. + format: int64 + type: integer + phase: + description: defines in what phase the IntegrationProfile is found + type: string + traits: + description: list of traits to be executed for all the Integration/IntegrationKits + built from this IntegrationProfile + properties: + 3scale: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + addons: + additionalProperties: + description: AddonTrait represents the configuration of an addon + trait. + type: object + x-kubernetes-preserve-unknown-fields: true + description: The extension point with addon traits + type: object + affinity: + description: The configuration of Affinity trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodeAffinityLabels: + description: Defines a set of nodes the integration pod(s) + are eligible to be scheduled on, based on labels on the + node. + items: + type: string + type: array + podAffinity: + description: Always co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should be co-located with. + items: + type: string + type: array + podAntiAffinity: + description: Never co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAntiAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should not be co-located with. + items: + type: string + type: array + type: object + builder: + description: The configuration of Builder trait + properties: + annotations: + additionalProperties: + type: string + description: When using `pod` strategy, annotation to use + for the builder pod. + type: object + baseImage: + description: Specify a base image + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + incrementalImageBuild: + description: Use the incremental image build option, to reuse + existing containers (default `true`) + type: boolean + limitCPU: + description: 'When using `pod` strategy, the maximum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + limitMemory: + description: 'When using `pod` strategy, the maximum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + mavenProfiles: + description: 'A list of references pointing to configmaps/secrets + that contains a maven profile. The content of the maven + profile is expected to be a text containing a valid maven + profile starting with `` and ending with `` + that will be integrated as an inline profile in the POM. + Syntax: [configmap|secret]:name[/key], where name represents + the resource name, key optionally represents the resource + key to be filtered (default key value = profile.xml).' + items: + type: string + type: array + nodeSelector: + additionalProperties: + type: string + description: Defines a set of nodes the builder pod is eligible + to be scheduled on, based on labels on the node. + type: object + orderStrategy: + description: The build order strategy to use, either `dependencies`, + `fifo` or `sequential` (default `sequential`) + enum: + - dependencies + - fifo + - sequential + type: string + properties: + description: A list of properties to be provided to the build + task + items: + type: string + type: array + requestCPU: + description: 'When using `pod` strategy, the minimum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + requestMemory: + description: 'When using `pod` strategy, the minimum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + strategy: + description: The strategy to use, either `pod` or `routine` + (default `routine`) + enum: + - pod + - routine + type: string + tasks: + description: A list of tasks to be executed (available only + when using `pod` strategy) with format `;;`. + items: + type: string + type: array + tasksFilter: + description: A list of tasks sorted by the order of execution + in a csv format, ie, `,,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only with `pod` strategy. + type: string + tasksLimitCPU: + description: A list of limit cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksLimitMemory: + description: A list of limit memory configuration for the + specific task with format `:`. + items: + type: string + type: array + tasksRequestCPU: + description: A list of request cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksRequestMemory: + description: A list of request memory configuration for the + specific task with format `:`. + items: + type: string + type: array + verbose: + description: Enable verbose logging on build components that + support it (e.g. Kaniko build pod). Deprecated no longer + in use + type: boolean + type: object + camel: + description: The configuration of Camel trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + properties: + description: A list of properties to be provided to the Integration + runtime + items: + type: string + type: array + runtimeVersion: + description: The camel-k-runtime version to use for the integration. + It overrides the default version set in the Integration + Platform. + type: string + type: object + container: + description: The configuration of Container trait + properties: + auto: + description: To automatically enable the trait + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + expose: + description: Can be used to enable/disable exposure via kubernetes + Service. + type: boolean + image: + description: The main container image + type: string + imagePullPolicy: + description: 'The pull policy: Always|Never|IfNotPresent' + enum: + - Always + - Never + - IfNotPresent + type: string + limitCPU: + description: The maximum amount of CPU required. + type: string + limitMemory: + description: The maximum amount of memory required. + type: string + name: + description: The main container name. It's named `integration` + by default. + type: string + port: + description: To configure a different port exposed by the + container (default `8080`). + type: integer + portName: + description: To configure a different port name for the port + exposed by the container. It defaults to `http` only when + the `expose` parameter is true. + type: string + requestCPU: + description: The minimum amount of CPU required. + type: string + requestMemory: + description: The minimum amount of memory required. + type: string + servicePort: + description: To configure under which service port the container + port is to be exposed (default `80`). + type: integer + servicePortName: + description: To configure under which service port name the + container port is to be exposed (default `http`). + type: string + type: object + cron: + description: The configuration of Cron trait + properties: + activeDeadlineSeconds: + description: Specifies the duration in seconds, relative to + the start time, that the job may be continuously active + before it is considered to be failed. It defaults to 60s. + format: int64 + type: integer + auto: + description: "Automatically deploy the integration as CronJob + when all routes are either starting from a periodic consumer + (only `cron`, `timer` and `quartz` are supported) or a passive + consumer (e.g. `direct` is a passive consumer). \n It's + required that all periodic consumers have the same period, + and it can be expressed as cron schedule (e.g. `1m` can + be expressed as `0/1 * * * *`, while `35m` or `50s` cannot)." + type: boolean + backoffLimit: + description: Specifies the number of retries before marking + the job failed. It defaults to 2. + format: int32 + type: integer + components: + description: "A comma separated list of the Camel components + that need to be customized in order for them to work when + the schedule is triggered externally by Kubernetes. A specific + customizer is activated for each specified component. E.g. + for the `timer` component, the `cron-timer` customizer is + activated (it's present in the `org.apache.camel.k:camel-k-cron` + library). \n Supported components are currently: `cron`, + `timer` and `quartz`." + type: string + concurrencyPolicy: + description: 'Specifies how to treat concurrent executions + of a Job. Valid values are: - "Allow": allows CronJobs to + run concurrently; - "Forbid" (default): forbids concurrent + runs, skipping next run if previous run hasn''t finished + yet; - "Replace": cancels currently running job and replaces + it with a new one' + enum: + - Allow + - Forbid + - Replace + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + fallback: + description: Use the default Camel implementation of the `cron` + endpoint (`quartz`) instead of trying to materialize the + integration as Kubernetes CronJob. + type: boolean + schedule: + description: The CronJob schedule for the whole integration. + If multiple routes are declared, they must have the same + schedule for this mechanism to work correctly. + type: string + startingDeadlineSeconds: + description: Optional deadline in seconds for starting the + job if it misses scheduled time for any reason. Missed + jobs executions will be counted as failed ones. + format: int64 + type: integer + type: object + dependencies: + description: The configuration of Dependencies trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + deployer: + description: The configuration of Deployer trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + kind: + description: Allows to explicitly select the desired deployment + kind between `deployment`, `cron-job` or `knative-service` + when creating the resources for running the integration. + enum: + - deployment + - cron-job + - knative-service + type: string + useSSA: + description: Use server-side apply to update the owned resources + (default `true`). Note that it automatically falls back + to client-side patching, if SSA is not available, e.g., + on old Kubernetes clusters. + type: boolean + type: object + deployment: + description: The configuration of Deployment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + progressDeadlineSeconds: + description: The maximum time in seconds for the deployment + to make progress before it is considered to be failed. It + defaults to `60s`. + format: int32 + type: integer + rollingUpdateMaxSurge: + description: 'The maximum number of pods that can be scheduled + above the desired number of pods. Value can be an absolute + number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. Absolute number + is calculated from percentage by rounding up. Defaults to + `25%`.' + type: integer + rollingUpdateMaxUnavailable: + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute number + is calculated from percentage by rounding down. This can + not be 0 if MaxSurge is 0. Defaults to `25%`.' + type: integer + strategy: + description: The deployment strategy to use to replace existing + pods with new ones. + enum: + - Recreate + - RollingUpdate + type: string + type: object + environment: + description: The configuration of Environment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + containerMeta: + description: Enables injection of `NAMESPACE` and `POD_NAME` + environment variables (default `true`) + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + httpProxy: + description: Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and + `NO_PROXY` environment variables (default `true`) + type: boolean + vars: + description: A list of environment variables to be added to + the integration container. The syntax is KEY=VALUE, e.g., + `MY_VAR="my value"`. These take precedence over the previously + defined environment variables. + items: + type: string + type: array + type: object + error-handler: + description: The configuration of Error Handler trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + ref: + description: The error handler ref name provided or found + in application properties + type: string + type: object + gc: + description: The configuration of GC trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryCache: + description: 'Discovery client cache to be used, either `disabled`, + `disk` or `memory` (default `memory`). Deprecated: to be + removed from trait configuration.' + enum: + - disabled + - disk + - memory + type: string + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + health: + description: The configuration of Health trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + livenessFailureThreshold: + description: Minimum consecutive failures for the liveness + probe to be considered failed after having succeeded. + format: int32 + type: integer + livenessInitialDelay: + description: Number of seconds after the container has started + before the liveness probe is initiated. + format: int32 + type: integer + livenessPeriod: + description: How often to perform the liveness probe. + format: int32 + type: integer + livenessProbeEnabled: + description: Configures the liveness probe for the integration + container (default `false`). + type: boolean + livenessScheme: + description: Scheme to use when connecting to the liveness + probe (default `HTTP`). + type: string + livenessSuccessThreshold: + description: Minimum consecutive successes for the liveness + probe to be considered successful after having failed. + format: int32 + type: integer + livenessTimeout: + description: Number of seconds after which the liveness probe + times out. + format: int32 + type: integer + readinessFailureThreshold: + description: Minimum consecutive failures for the readiness + probe to be considered failed after having succeeded. + format: int32 + type: integer + readinessInitialDelay: + description: Number of seconds after the container has started + before the readiness probe is initiated. + format: int32 + type: integer + readinessPeriod: + description: How often to perform the readiness probe. + format: int32 + type: integer + readinessProbeEnabled: + description: Configures the readiness probe for the integration + container (default `true`). + type: boolean + readinessScheme: + description: Scheme to use when connecting to the readiness + probe (default `HTTP`). + type: string + readinessSuccessThreshold: + description: Minimum consecutive successes for the readiness + probe to be considered successful after having failed. + format: int32 + type: integer + readinessTimeout: + description: Number of seconds after which the readiness probe + times out. + format: int32 + type: integer + startupFailureThreshold: + description: Minimum consecutive failures for the startup + probe to be considered failed after having succeeded. + format: int32 + type: integer + startupInitialDelay: + description: Number of seconds after the container has started + before the startup probe is initiated. + format: int32 + type: integer + startupPeriod: + description: How often to perform the startup probe. + format: int32 + type: integer + startupProbeEnabled: + description: Configures the startup probe for the integration + container (default `false`). + type: boolean + startupScheme: + description: Scheme to use when connecting to the startup + probe (default `HTTP`). + type: string + startupSuccessThreshold: + description: Minimum consecutive successes for the startup + probe to be considered successful after having failed. + format: int32 + type: integer + startupTimeout: + description: Number of seconds after which the startup probe + times out. + format: int32 + type: integer + type: object + ingress: + description: The configuration of Ingress trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to the ingress. This can + be used to set controller specific annotations, e.g., when + using the NGINX Ingress controller: See https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md' + type: object + auto: + description: To automatically add an ingress whenever the + integration uses an HTTP endpoint consumer. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the ingress. + type: string + path: + description: To configure the path exposed by the ingress + (default `/`). + type: string + pathType: + description: To configure the path type exposed by the ingress. + One of `Exact`, `Prefix`, `ImplementationSpecific` (default + to `Prefix`). + enum: + - Exact + - Prefix + - ImplementationSpecific + type: string + type: object + istio: + description: The configuration of Istio trait + properties: + allow: + description: Configures a (comma-separated) list of CIDR subnets + that should not be intercepted by the Istio proxy (`10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` + by default). + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + inject: + description: Forces the value for labels `sidecar.istio.io/inject`. + By default the label is set to `true` on deployment and + not set on Knative Service. + type: boolean + type: object + jolokia: + description: The configuration of Jolokia trait + properties: + CACert: + description: The PEM encoded CA certification file path, used + to verify client certificates, applicable when `protocol` + is `https` and `use-ssl-client-authentication` is `true` + (default `/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt` + for OpenShift). + type: string + clientPrincipal: + description: The principal(s) which must be given in a client + certificate to allow access to the Jolokia endpoint, applicable + when `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `clientPrincipal=cn=system:master-proxy`, + `cn=hawtio-online.hawtio.svc` and `cn=fuse-console.fuse.svc` + for OpenShift). + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryEnabled: + description: Listen for multicast requests (default `false`) + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + extendedClientCheck: + description: Mandate the client certificate contains a client + flag in the extended key usage section, applicable when + `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `true` for OpenShift). + type: boolean + host: + description: The Host address to which the Jolokia agent should + bind to. If `"\*"` or `"0.0.0.0"` is given, the servers + binds to every network interface (default `"*"`). + type: string + options: + description: A list of additional Jolokia options as defined + in https://jolokia.org/reference/html/agents.html#agent-jvm-config[JVM + agent configuration options] + items: + type: string + type: array + password: + description: The password used for authentication, applicable + when the `user` option is set. + type: string + port: + description: The Jolokia endpoint port (default `8778`). + type: integer + protocol: + description: The protocol to use, either `http` or `https` + (default `https` for OpenShift) + type: string + useSSLClientAuthentication: + description: Whether client certificates should be used for + authentication (default `true` for OpenShift). + type: boolean + user: + description: The user to be used for authentication + type: string + type: object + jvm: + description: The configuration of JVM trait + properties: + classpath: + description: Additional JVM classpath (use `Linux` classpath + separator) + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + debug: + description: Activates remote debugging, so that a debugger + can be attached to the JVM, e.g., using port-forwarding + type: boolean + debugAddress: + description: Transport address at which to listen for the + newly launched JVM (default `*:5005`) + type: string + debugSuspend: + description: Suspends the target JVM immediately before the + main class is loaded + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + options: + description: A list of JVM options + items: + type: string + type: array + printCommand: + description: Prints the command used the start the JVM in + the container logs (default `true`) + type: boolean + type: object + kamelets: + description: The configuration of Kamelets trait + properties: + auto: + description: Automatically inject all referenced Kamelets + and their default configuration (enabled by default) + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + list: + description: Comma separated list of Kamelet names to load + into the current integration + type: string + mountPoint: + description: The directory where the application mounts and + reads Kamelet spec (default `/etc/camel/kamelets`) + type: string + type: object + keda: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + knative: + description: The configuration of Knative trait + properties: + auto: + description: Enable automatic discovery of all trait properties. + type: boolean + channelSinks: + description: List of channels used as destination of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + channelSources: + description: List of channels used as source of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + config: + description: Can be used to inject a Knative complete configuration + in JSON format. + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + endpointSinks: + description: List of endpoints used as destination of integration + routes. Can contain simple endpoint names or full Camel + URIs. + items: + type: string + type: array + endpointSources: + description: List of channels used as source of integration + routes. + items: + type: string + type: array + eventSinks: + description: List of event types that the integration will + produce. Can contain simple event types or full Camel URIs + (to use a specific broker). + items: + type: string + type: array + eventSources: + description: List of event types that the integration will + be subscribed to. Can contain simple event types or full + Camel URIs (to use a specific broker different from "default"). + items: + type: string + type: array + filterSourceChannels: + description: Enables filtering on events based on the header + "ce-knativehistory". Since this header has been removed + in newer versions of Knative, filtering is disabled by default. + type: boolean + namespaceLabel: + description: 'Enables the camel-k-operator to set the "bindings.knative.dev/include=true" + label to the namespace As Knative requires this label to + perform injection of K_SINK URL into the service. If this + is false, the integration pod may start and fail, read the + SinkBinding Knative documentation. (default: true)' + type: boolean + sinkBinding: + description: Allows binding the integration to a sink via + a Knative SinkBinding resource. This can be used when the + integration targets a single sink. It's enabled by default + when the integration targets a single sink (except when + the integration is owned by a Knative source). + type: boolean + type: object + knative-service: + description: The configuration of Knative Service trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set knative service specific annotations CLI usage + example: -t "knative-service.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + auto: + description: "Automatically deploy the integration as Knative + service when all conditions hold: \n * Integration is using + the Knative profile * All routes are either starting from + an HTTP based consumer or a passive consumer (e.g. `direct` + is a passive consumer)" + type: boolean + autoscalingMetric: + description: "Configures the Knative autoscaling metric property + (e.g. to set `concurrency` based or `cpu` based autoscaling). + \n Refer to the Knative documentation for more information." + type: string + autoscalingTarget: + description: "Sets the allowed concurrency level or CPU percentage + (depending on the autoscaling metric) for each Pod. \n Refer + to the Knative documentation for more information." + type: integer + class: + description: "Configures the Knative autoscaling class property + (e.g. to set `hpa.autoscaling.knative.dev` or `kpa.autoscaling.knative.dev` + autoscaling). \n Refer to the Knative documentation for + more information." + enum: + - kpa.autoscaling.knative.dev + - hpa.autoscaling.knative.dev + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxScale: + description: "An upper bound for the number of Pods that can + be running in parallel for the integration. Knative has + its own cap value that depends on the installation. \n Refer + to the Knative documentation for more information." + type: integer + minScale: + description: "The minimum number of Pods that should be running + at any time for the integration. It's **zero** by default, + meaning that the integration is scaled down to zero when + not used for a configured amount of time. \n Refer to the + Knative documentation for more information." + type: integer + rolloutDuration: + description: Enables to gradually shift traffic to the latest + Revision and sets the rollout duration. It's disabled by + default and must be expressed as a Golang `time.Duration` + string representation, rounded to a second precision. + type: string + visibility: + description: "Setting `cluster-local`, Knative service becomes + a private service. Specifically, this option applies the + `networking.knative.dev/visibility` label to Knative service. + \n Refer to the Knative documentation for more information." + enum: + - cluster-local + type: string + type: object + logging: + description: The configuration of Logging trait + properties: + color: + description: Colorize the log output + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + format: + description: Logs message format + type: string + json: + description: Output the logs in JSON + type: boolean + jsonPrettyPrint: + description: Enable "pretty printing" of the JSON logs + type: boolean + level: + description: Adjust the logging level (defaults to `INFO`) + enum: + - FATAL + - WARN + - INFO + - DEBUG + - TRACE + type: string + type: object + master: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + mount: + description: The configuration of Mount trait + properties: + configs: + description: 'A list of configuration pointing to configmap/secret. + The configuration are expected to be UTF-8 resources as + they are processed by runtime Camel Context and tried to + be parsed as property files. They are also made available + on the classpath in order to ease their usage directly from + the Route. Syntax: [configmap|secret]:name[/key], where + name represents the resource name and key optionally represents + the resource key to be filtered' + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + hotReload: + description: Enable "hot reload" when a secret/configmap mounted + is edited (default `false`). The configmap/secret must be + marked with `camel.apache.org/integration` label to be taken + in account. + type: boolean + resources: + description: 'A list of resources (text or binary content) + pointing to configmap/secret. The resources are expected + to be any resource type (text or binary content). The destination + path can be either a default location or any path specified + by the user. Syntax: [configmap|secret]:name[/key][@path], + where name represents the resource name, key optionally + represents the resource key to be filtered and path represents + the destination path' + items: + type: string + type: array + volumes: + description: 'A list of Persistent Volume Claims to be mounted. + Syntax: [pvcname:/container/path]' + items: + type: string + type: array + type: object + openapi: + description: The configuration of OpenAPI trait + properties: + configmaps: + description: The configmaps holding the spec of the OpenAPI + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + owner: + description: The configuration of Owner trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + targetAnnotations: + description: The set of annotations to be transferred + items: + type: string + type: array + targetLabels: + description: The set of labels to be transferred + items: + type: string + type: array + type: object + pdb: + description: The configuration of PDB trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxUnavailable: + description: The number of pods for the Integration that can + be unavailable after an eviction. It can be either an absolute + number or a percentage (default `1` if `min-available` is + also not set). Only one of `max-unavailable` and `min-available` + can be specified. + type: string + minAvailable: + description: The number of pods for the Integration that must + still be available after an eviction. It can be either an + absolute number or a percentage. Only one of `min-available` + and `max-unavailable` can be specified. + type: string + type: object + platform: + description: The configuration of Platform trait + properties: + auto: + description: 'To automatically detect from the environment + if a default platform can be created (it will be created + on OpenShift or when a registry address is set). Deprecated: + Platform is auto generated by the operator install procedure + - maintained for backward compatibility' + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + createDefault: + description: 'To create a default (empty) platform when the + platform is missing. Deprecated: Platform is auto generated + by the operator install procedure - maintained for backward + compatibility' + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + global: + description: 'Indicates if the platform should be created + globally in the case of global operator (default true). + Deprecated: Platform is auto generated by the operator install + procedure - maintained for backward compatibility' + type: boolean + type: object + pod: + description: The configuration of Pod trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + prometheus: + description: The configuration of Prometheus trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + podMonitor: + description: Whether a `PodMonitor` resource is created (default + `true`). + type: boolean + podMonitorLabels: + description: The `PodMonitor` resource labels, applicable + when `pod-monitor` is `true`. + items: + type: string + type: array + type: object + pull-secret: + description: The configuration of Pull Secret trait + properties: + auto: + description: Automatically configures the platform registry + secret on the pod if it is of type `kubernetes.io/dockerconfigjson`. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + imagePullerDelegation: + description: When using a global operator with a shared platform, + this enables delegation of the `system:image-puller` cluster + role on the operator namespace to the integration service + account. + type: boolean + secretName: + description: The pull secret name to set on the Pod. If left + empty this is automatically taken from the `IntegrationPlatform` + registry configuration. + type: string + type: object + quarkus: + description: The configuration of Quarkus trait + properties: + buildMode: + description: 'The Quarkus mode to run: either `jvm` or `native` + (default `jvm`). In case both `jvm` and `native` are specified, + two `IntegrationKit` resources are created, with the `native` + kit having precedence over the `jvm` one once ready.' + items: + description: QuarkusMode is the type of Quarkus build packaging. + enum: + - jvm + - native + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + nativeBaseImage: + description: The base image to use when running a native build + (default `quay.io/quarkus/quarkus-micro-image:2.0`) + type: string + nativeBuilderImage: + description: The image containing the tooling required for + a native build (by default it will use the one provided + in the runtime catalog) + type: string + packageTypes: + description: 'The Quarkus package types, `fast-jar` or `native` + (default `fast-jar`). In case both `fast-jar` and `native` + are specified, two `IntegrationKit` resources are created, + with the native kit having precedence over the `fast-jar` + one once ready. The order influences the resolution of the + current kit for the integration. The kit corresponding to + the first package type will be assigned to the integration + in case no existing kit that matches the integration exists. + Deprecated: use `build-mode` instead.' + items: + description: 'QuarkusPackageType is the type of Quarkus + build packaging. Deprecated: use `QuarkusMode` instead.' + enum: + - fast-jar + - native + type: string + type: array + type: object + registry: + description: The configuration of Registry trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + route: + description: The configuration of Route trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set route specific annotations For annotations options + see https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#route-specific-annotations + CLI usage example: -t "route.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the route. + type: string + tlsCACertificate: + description: "The TLS CA certificate contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsCACertificateSecret: + description: "The secret name and key reference to the TLS + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsCertificate: + description: "The TLS certificate contents. \n Refer to the + OpenShift route documentation for additional information." + type: string + tlsCertificateSecret: + description: "The secret name and key reference to the TLS + certificate. The format is \"secret-name[/key-name]\", the + value represents the secret name, if there is only one key + in the secret it will be read, otherwise you can set a key + name separated with a \"/\". \n Refer to the OpenShift route + documentation for additional information." + type: string + tlsDestinationCACertificate: + description: "The destination CA certificate provides the + contents of the ca certificate of the final destination. + \ When using reencrypt termination this file should be provided + in order to have routers use it for health checks on the + secure connection. If this field is not specified, the router + may provide its own destination CA and perform hostname + validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to automatically + verify. \n Refer to the OpenShift route documentation for + additional information." + type: string + tlsDestinationCACertificateSecret: + description: "The secret name and key reference to the destination + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsInsecureEdgeTerminationPolicy: + description: "To configure how to deal with insecure traffic, + e.g. `Allow`, `Disable` or `Redirect` traffic. \n Refer + to the OpenShift route documentation for additional information." + enum: + - None + - Allow + - Redirect + type: string + tlsKey: + description: "The TLS certificate key contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsKeySecret: + description: "The secret name and key reference to the TLS + certificate key. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsTermination: + description: "The TLS termination type, like `edge`, `passthrough` + or `reencrypt`. \n Refer to the OpenShift route documentation + for additional information." + enum: + - edge + - reencrypt + - passthrough + type: string + type: object + service: + description: The configuration of Service trait + properties: + auto: + description: To automatically detect from the code if a Service + needs to be created. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodePort: + description: 'Enable Service to be exposed as NodePort (default + `false`). Deprecated: Use service type instead.' + type: boolean + type: + description: The type of service to be used, either 'ClusterIP', + 'NodePort' or 'LoadBalancer'. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + type: object + service-binding: + description: The configuration of Service Binding trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + services: + description: List of Services in the form [[apigroup/]version:]kind:[namespace/]name + items: + type: string + type: array + type: object + strimzi: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + toleration: + description: The configuration of Toleration trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + taints: + description: The list of taints to tolerate, in the form `Key[=Value]:Effect[:Seconds]` + items: + type: string + type: array + type: object + tracing: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/helm/camel-k/templates/operator-cluster-roles.yaml b/helm/camel-k/templates/operator-cluster-roles.yaml index ac1da0ca8b..f4d9704098 100644 --- a/helm/camel-k/templates/operator-cluster-roles.yaml +++ b/helm/camel-k/templates/operator-cluster-roles.yaml @@ -34,6 +34,7 @@ rules: - camelcatalogs - integrationkits - integrationplatforms + - integrationprofiles - integrations - pipes # Deprecated: kameletbindings CR @@ -55,6 +56,7 @@ rules: - camelcatalogs/status - integrationkits/status - integrationplatforms/status + - integrationprofiles/status - integrations/scale - integrations/status - pipes/status @@ -85,6 +87,7 @@ rules: - camelcatalogs - integrationkits - integrationplatforms + - integrationprofiles - integrations - pipes # Deprecated: kameletbindings CR @@ -110,6 +113,7 @@ rules: - camelcatalogs/status - integrationkits/status - integrationplatforms/status + - integrationprofiles/status - integrations/scale - integrations/status - pipes/status @@ -466,6 +470,7 @@ rules: - builds/finalizers - integrationkits/finalizers - integrationplatforms/finalizers + - integrationprofiles/finalizers - integrations/finalizers - pipes/finalizers - kameletbindings/finalizers @@ -537,4 +542,4 @@ rules: - create {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/helm/camel-k/templates/operator-role.yaml b/helm/camel-k/templates/operator-role.yaml index 40ef9742ac..d035280f8b 100644 --- a/helm/camel-k/templates/operator-role.yaml +++ b/helm/camel-k/templates/operator-role.yaml @@ -31,6 +31,7 @@ rules: - camelcatalogs - integrationkits - integrationplatforms + - integrationprofiles - integrations - pipes # Deprecated: kameletbindings CR @@ -64,6 +65,7 @@ rules: - camelcatalogs/status - integrationkits/status - integrationplatforms/status + - integrationprofiles/status - integrations/scale - integrations/status - pipes/status @@ -277,6 +279,7 @@ rules: - builds/finalizers - integrationkits/finalizers - integrationplatforms/finalizers + - integrationprofiles/finalizers - integrations/finalizers - pipes/finalizers - kameletbindings/finalizers diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go index 24e57130c6..cb01b391f4 100644 --- a/pkg/apis/camel/v1/common_types.go +++ b/pkg/apis/camel/v1/common_types.go @@ -29,10 +29,12 @@ const ( TraitAnnotationPrefix = "trait.camel.apache.org/" // OperatorIDAnnotation operator id annotation label. OperatorIDAnnotation = "camel.apache.org/operator.id" - // SecondaryPlatformAnnotation secondary platform annotation label. - SecondaryPlatformAnnotation = "camel.apache.org/secondary.platform" // PlatformSelectorAnnotation platform id annotation label. PlatformSelectorAnnotation = "camel.apache.org/platform.id" + // IntegrationProfileAnnotation integration profile id annotation label. + IntegrationProfileAnnotation = "camel.apache.org/integration-profile.id" + // IntegrationProfileNamespaceAnnotation integration profile id annotation label. + IntegrationProfileNamespaceAnnotation = "camel.apache.org/integration-profile.namespace" ) // BuildConfiguration represent the configuration required to build the runtime. diff --git a/pkg/apis/camel/v1/common_types_support.go b/pkg/apis/camel/v1/common_types_support.go index 4e7b54dc88..0c86fae7be 100644 --- a/pkg/apis/camel/v1/common_types_support.go +++ b/pkg/apis/camel/v1/common_types_support.go @@ -101,6 +101,44 @@ func (t *Traits) Merge(other Traits) error { return nil } +// Merge merges the given IntegrationKitTraits into the receiver. +func (t *IntegrationKitTraits) Merge(other IntegrationKitTraits) error { + // marshal both + data1, err := json.Marshal(t) + if err != nil { + return err + } + data2, err := json.Marshal(other) + if err != nil { + return err + } + + // merge them + map1 := make(map[string]interface{}) + if err := json.Unmarshal(data1, &map1); err != nil { + return err + } + map2 := make(map[string]interface{}) + if err := json.Unmarshal(data2, &map2); err != nil { + return err + } + // values from merged trait take precedence over the original ones + if err := mergo.Merge(&map1, map2, mergo.WithOverride); err != nil { + return err + } + + // unmarshal it + data, err := json.Marshal(map1) + if err != nil { + return err + } + if err = json.Unmarshal(data, &t); err != nil { + return err + } + + return nil +} + // MarshalJSON returns m as the JSON encoding of m. func (m RawMessage) MarshalJSON() ([]byte, error) { if m == nil { @@ -135,12 +173,27 @@ var _ json.Unmarshaler = (*RawMessage)(nil) // GetOperatorIDAnnotation to safely get the operator id annotation value. func GetOperatorIDAnnotation(obj metav1.Object) string { + return GetAnnotation(OperatorIDAnnotation, obj) +} + +// GetIntegrationProfileAnnotation to safely get the integration profile annotation value. +func GetIntegrationProfileAnnotation(obj metav1.Object) string { + return GetAnnotation(IntegrationProfileAnnotation, obj) +} + +// GetIntegrationProfileNamespaceAnnotation to safely get the integration profile namespace annotation value. +func GetIntegrationProfileNamespaceAnnotation(obj metav1.Object) string { + return GetAnnotation(IntegrationProfileNamespaceAnnotation, obj) +} + +// GetAnnotation safely get the annotation value. +func GetAnnotation(name string, obj metav1.Object) string { if obj == nil || obj.GetAnnotations() == nil { return "" } - if operatorID, ok := obj.GetAnnotations()[OperatorIDAnnotation]; ok { - return operatorID + if annotation, ok := obj.GetAnnotations()[name]; ok { + return annotation } return "" diff --git a/pkg/apis/camel/v1/common_types_support_test.go b/pkg/apis/camel/v1/common_types_support_test.go index 2642f96dba..36c1f9e9e7 100644 --- a/pkg/apis/camel/v1/common_types_support_test.go +++ b/pkg/apis/camel/v1/common_types_support_test.go @@ -93,6 +93,74 @@ func TestTraitsMerge(t *testing.T) { t1.Addons["telemetry"]) } +func TestIntegrationKitTraitsMerge(t *testing.T) { + t1 := IntegrationKitTraits{ + Builder: &trait.BuilderTrait{ + Properties: []string{ + "b1=value_b1", + }, + }, + Camel: &trait.CamelTrait{ + RuntimeVersion: "0.99.0", + Properties: []string{ + "c1=value_c1", + }, + }, + Addons: map[string]AddonTrait{ + "master": toAddonTrait(t, map[string]interface{}{ + "resourceName": "test-lock", + }), + "telemetry": toAddonTrait(t, map[string]interface{}{ + "enabled": true, + }), + }, + } + t2 := IntegrationKitTraits{ + Builder: &trait.BuilderTrait{ + Properties: []string{ + "b2=value_b2", + }, + }, + Quarkus: &trait.QuarkusTrait{ + NativeBaseImage: "quay.io/quarkus/quarkus-micro-image:2.0", + }, + Addons: map[string]AddonTrait{ + "telemetry": toAddonTrait(t, map[string]interface{}{ + "serviceName": "test-integration", + }), + }, + } + + err := t1.Merge(t2) + + require.NoError(t, err) + + assert.NotNil(t, t1.Builder) + assert.Equal(t, 1, len(t1.Builder.Properties)) + assert.Equal(t, "b2=value_b2", t1.Builder.Properties[0]) + + assert.NotNil(t, t1.Camel) + assert.Equal(t, "0.99.0", t1.Camel.RuntimeVersion) + assert.Equal(t, 1, len(t1.Camel.Properties)) + assert.Equal(t, "c1=value_c1", t1.Camel.Properties[0]) + + assert.NotNil(t, t1.Quarkus) + assert.Equal(t, "quay.io/quarkus/quarkus-micro-image:2.0", t1.Quarkus.NativeBaseImage) + + assert.NotNil(t, t1.Addons) + assert.Equal(t, + toAddonTrait(t, map[string]interface{}{ + "resourceName": "test-lock", + }), + t1.Addons["master"]) + assert.Equal(t, + toAddonTrait(t, map[string]interface{}{ + "enabled": true, + "serviceName": "test-integration", + }), + t1.Addons["telemetry"]) +} + func TestDecodeValueSourceValid(t *testing.T) { res, err := DecodeValueSource("configmap:my-configmap", "defaultkey", "errorMessage") require.NoError(t, err) diff --git a/pkg/apis/camel/v1/integrationplatform_types.go b/pkg/apis/camel/v1/integrationplatform_types.go index 67707a4db6..3adb130796 100644 --- a/pkg/apis/camel/v1/integrationplatform_types.go +++ b/pkg/apis/camel/v1/integrationplatform_types.go @@ -189,8 +189,6 @@ const ( IntegrationPlatformPhaseError IntegrationPlatformPhase = "Error" // IntegrationPlatformPhaseCreateCatalog when the IntegrationPlatform creates a new CamelCatalog. IntegrationPlatformPhaseCreateCatalog IntegrationPlatformPhase = "CreateCatalog" - // IntegrationPlatformPhaseDuplicate when the IntegrationPlatform is duplicated. - IntegrationPlatformPhaseDuplicate IntegrationPlatformPhase = "Duplicate" // IntegrationPlatformConditionReady is the condition if the IntegrationPlatform is ready. // Deprecated: use IntegrationPlatformConditionTypeCreated. diff --git a/pkg/apis/camel/v1/integrationprofile_types.go b/pkg/apis/camel/v1/integrationprofile_types.go new file mode 100644 index 0000000000..4b85289b66 --- /dev/null +++ b/pkg/apis/camel/v1/integrationprofile_types.go @@ -0,0 +1,138 @@ +/* +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 v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. +// Important: Run "make generate-deepcopy" to regenerate code after modifying this file + +// IntegrationProfileSpec applies user defined settings to the IntegrationProfile. +type IntegrationProfileSpec struct { + // specify how to build the Integration/IntegrationKits + Build IntegrationProfileBuildSpec `json:"build,omitempty"` + // list of traits to be executed for all the Integration/IntegrationKits built from this IntegrationProfile + Traits Traits `json:"traits,omitempty"` + // configuration to be executed to all Kamelets controlled by this IntegrationProfile + Kamelet IntegrationProfileKameletSpec `json:"kamelet,omitempty"` +} + +// IntegrationProfileStatus defines the observed state of IntegrationProfile. +type IntegrationProfileStatus struct { + IntegrationProfileSpec `json:",inline"` + // ObservedGeneration is the most recent generation observed for this IntegrationProfile. + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + // defines in what phase the IntegrationProfile is found + Phase IntegrationProfilePhase `json:"phase,omitempty"` + // which are the conditions met (particularly useful when in ERROR phase) + Conditions []IntegrationProfileCondition `json:"conditions,omitempty"` +} + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:resource:path=integrationprofiles,scope=Namespaced,shortName=ipr,categories=kamel;camel +// +kubebuilder:subresource:status +// +kubebuilder:storageversion +// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`,description="The integration profile phase" +// +kubebuilder:printcolumn:name="Default runtime",type=string,JSONPath=`.status.build.runtimeVersion`,description="The default runtime version" + +// IntegrationProfile is the resource used to apply user defined settings to the Camel K operator behavior. +// It defines the behavior of all Custom Resources (`IntegrationKit`, `Integration`, `Kamelet`) in the given namespace. +type IntegrationProfile struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec IntegrationProfileSpec `json:"spec,omitempty"` + Status IntegrationProfileStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// IntegrationProfileList contains a list of IntegrationProfile. +type IntegrationProfileList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []IntegrationProfile `json:"items"` +} + +// IntegrationProfileBuildSpec contains profile related build information. +// This configuration can be used to tune the behavior of the Integration/IntegrationKit image builds. +type IntegrationProfileBuildSpec struct { + // the Camel K Runtime dependency version + RuntimeVersion string `json:"runtimeVersion,omitempty"` + // the runtime used. Likely Camel Quarkus (we used to have main runtime which has been discontinued since version 1.5) + RuntimeProvider RuntimeProvider `json:"runtimeProvider,omitempty"` + // a base image that can be used as base layer for all images. + // It can be useful if you want to provide some custom base image with further utility software + BaseImage string `json:"baseImage,omitempty"` + // the image registry used to push/pull Integration images + Registry RegistrySpec `json:"registry,omitempty"` + // how much time to wait before time out the pipeline process + Timeout *metav1.Duration `json:"timeout,omitempty"` + // Maven configuration used to build the Camel/Camel-Quarkus applications + Maven MavenSpec `json:"maven,omitempty"` +} + +// IntegrationProfileKameletSpec define the behavior for all the Kamelets controller by the IntegrationProfile. +type IntegrationProfileKameletSpec struct { + // remote repository used to retrieve Kamelet catalog + Repositories []KameletRepositorySpec `json:"repositories,omitempty"` +} + +// IntegrationProfilePhase is the phase of an IntegrationProfile. +type IntegrationProfilePhase string + +// IntegrationProfileConditionType defines the type of condition. +type IntegrationProfileConditionType string + +const ( + // IntegrationProfileKind is the Kind name of the IntegrationProfile CR. + IntegrationProfileKind string = "IntegrationProfile" + + // IntegrationProfilePhaseNone when the IntegrationProfile does not exist. + IntegrationProfilePhaseNone IntegrationProfilePhase = "" + // IntegrationProfilePhaseReady when the IntegrationProfile is ready. + IntegrationProfilePhaseReady IntegrationProfilePhase = "Ready" + // IntegrationProfilePhaseError when the IntegrationProfile had some error (see Conditions). + IntegrationProfilePhaseError IntegrationProfilePhase = "Error" + + // IntegrationProfileConditionTypeCreated is the condition if the IntegrationProfile has been created. + IntegrationProfileConditionTypeCreated IntegrationProfileConditionType = "Created" + + // IntegrationProfileConditionCreatedReason represents the reason that the IntegrationProfile is created. + IntegrationProfileConditionCreatedReason = "IntegrationProfileCreated" +) + +// IntegrationProfileCondition describes the state of a resource at a certain point. +type IntegrationProfileCondition struct { + // Type of integration condition. + Type IntegrationProfileConditionType `json:"type"` + // Status of the condition, one of True, False, Unknown. + Status corev1.ConditionStatus `json:"status"` + // The last time this condition was updated. + LastUpdateTime metav1.Time `json:"lastUpdateTime,omitempty"` + // Last time the condition transitioned from one status to another. + LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` + // The reason for the condition's last transition. + Reason string `json:"reason,omitempty"` + // A human-readable message indicating details about the transition. + Message string `json:"message,omitempty"` +} diff --git a/pkg/apis/camel/v1/integrationprofile_types_support.go b/pkg/apis/camel/v1/integrationprofile_types_support.go new file mode 100644 index 0000000000..76c5e88d4f --- /dev/null +++ b/pkg/apis/camel/v1/integrationprofile_types_support.go @@ -0,0 +1,191 @@ +/* +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 v1 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// NewIntegrationProfileList --. +func NewIntegrationProfileList() IntegrationProfileList { + return IntegrationProfileList{ + TypeMeta: metav1.TypeMeta{ + APIVersion: SchemeGroupVersion.String(), + Kind: IntegrationProfileKind, + }, + } +} + +// NewIntegrationProfile --. +func NewIntegrationProfile(namespace string, name string) IntegrationProfile { + return IntegrationProfile{ + TypeMeta: metav1.TypeMeta{ + APIVersion: SchemeGroupVersion.String(), + Kind: IntegrationProfileKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + } +} + +// SetOperatorID sets the given operator id as an annotation. +func (in *IntegrationProfile) SetOperatorID(operatorID string) { + SetAnnotation(&in.ObjectMeta, OperatorIDAnnotation, operatorID) +} + +// GetActualValue can be used to extract information the platform spec or its derived config in the status. +func (in *IntegrationProfile) GetActualValue(extractor func(spec IntegrationProfileSpec) string) string { + res := extractor(in.Status.IntegrationProfileSpec) + if res == "" { + res = extractor(in.Spec) + } + return res +} + +// ResyncStatusFullConfig copies the spec configuration into the status field. +func (in *IntegrationProfile) ResyncStatusFullConfig() { + cl := in.Spec.DeepCopy() + in.Status.IntegrationProfileSpec = *cl +} + +// GetCondition returns the condition with the provided type. +func (in *IntegrationProfileStatus) GetCondition(condType IntegrationProfileConditionType) *IntegrationProfileCondition { + for i := range in.Conditions { + c := in.Conditions[i] + if c.Type == condType { + return &c + } + } + return nil +} + +// SetCondition sets the condition with the given status, reason, and message. +func (in *IntegrationProfileStatus) SetCondition(condType IntegrationProfileConditionType, status corev1.ConditionStatus, reason string, message string) { + in.SetConditions(IntegrationProfileCondition{ + Type: condType, + Status: status, + LastUpdateTime: metav1.Now(), + LastTransitionTime: metav1.Now(), + Reason: reason, + Message: message, + }) +} + +// SetErrorCondition sets the condition with the given reason and error message. +func (in *IntegrationProfileStatus) SetErrorCondition(condType IntegrationProfileConditionType, reason string, err error) { + in.SetConditions(IntegrationProfileCondition{ + Type: condType, + Status: corev1.ConditionFalse, + LastUpdateTime: metav1.Now(), + LastTransitionTime: metav1.Now(), + Reason: reason, + Message: err.Error(), + }) +} + +// SetConditions updates the resource to include the provided conditions. +// +// If a condition that we are about to add already exists and has the same status and +// reason then we are not going to update. +func (in *IntegrationProfileStatus) SetConditions(conditions ...IntegrationProfileCondition) { + for _, condition := range conditions { + if condition.LastUpdateTime.IsZero() { + condition.LastUpdateTime = metav1.Now() + } + if condition.LastTransitionTime.IsZero() { + condition.LastTransitionTime = metav1.Now() + } + + currentCond := in.GetCondition(condition.Type) + + if currentCond != nil && currentCond.Status == condition.Status && currentCond.Reason == condition.Reason { + return + } + // Do not update lastTransitionTime if the status of the condition doesn't change. + if currentCond != nil && currentCond.Status == condition.Status { + condition.LastTransitionTime = currentCond.LastTransitionTime + } + + in.RemoveCondition(condition.Type) + in.Conditions = append(in.Conditions, condition) + } +} + +// RemoveCondition removes the resource condition with the provided type. +func (in *IntegrationProfileStatus) RemoveCondition(condType IntegrationProfileConditionType) { + newConditions := in.Conditions[:0] + for _, c := range in.Conditions { + if c.Type != condType { + newConditions = append(newConditions, c) + } + } + + in.Conditions = newConditions +} + +// GetTimeout returns the specified duration or a default one. +func (b IntegrationProfileBuildSpec) GetTimeout() metav1.Duration { + if b.Timeout == nil { + return metav1.Duration{} + } + return *b.Timeout +} + +var _ ResourceCondition = IntegrationProfileCondition{} + +// GetConditions --. +func (in *IntegrationProfileStatus) GetConditions() []ResourceCondition { + res := make([]ResourceCondition, 0, len(in.Conditions)) + for _, c := range in.Conditions { + res = append(res, c) + } + return res +} + +// GetType --. +func (c IntegrationProfileCondition) GetType() string { + return string(c.Type) +} + +// GetStatus --. +func (c IntegrationProfileCondition) GetStatus() corev1.ConditionStatus { + return c.Status +} + +// GetLastUpdateTime --. +func (c IntegrationProfileCondition) GetLastUpdateTime() metav1.Time { + return c.LastUpdateTime +} + +// GetLastTransitionTime --. +func (c IntegrationProfileCondition) GetLastTransitionTime() metav1.Time { + return c.LastTransitionTime +} + +// GetReason --. +func (c IntegrationProfileCondition) GetReason() string { + return c.Reason +} + +// GetMessage --. +func (c IntegrationProfileCondition) GetMessage() string { + return c.Message +} diff --git a/pkg/apis/camel/v1/register.go b/pkg/apis/camel/v1/register.go index 42a0410961..d02b982bb4 100644 --- a/pkg/apis/camel/v1/register.go +++ b/pkg/apis/camel/v1/register.go @@ -53,6 +53,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &IntegrationKitList{}, &IntegrationPlatform{}, &IntegrationPlatformList{}, + &IntegrationProfile{}, + &IntegrationProfileList{}, &CamelCatalog{}, &CamelCatalogList{}, &Build{}, diff --git a/pkg/apis/camel/v1/zz_generated.deepcopy.go b/pkg/apis/camel/v1/zz_generated.deepcopy.go index 5cc7ccc1f4..ded77d34ba 100644 --- a/pkg/apis/camel/v1/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1/zz_generated.deepcopy.go @@ -1551,6 +1551,165 @@ func (in *IntegrationPlatformStatus) DeepCopy() *IntegrationPlatformStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntegrationProfile) DeepCopyInto(out *IntegrationProfile) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationProfile. +func (in *IntegrationProfile) DeepCopy() *IntegrationProfile { + if in == nil { + return nil + } + out := new(IntegrationProfile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IntegrationProfile) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntegrationProfileBuildSpec) DeepCopyInto(out *IntegrationProfileBuildSpec) { + *out = *in + out.Registry = in.Registry + if in.Timeout != nil { + in, out := &in.Timeout, &out.Timeout + *out = new(metav1.Duration) + **out = **in + } + in.Maven.DeepCopyInto(&out.Maven) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationProfileBuildSpec. +func (in *IntegrationProfileBuildSpec) DeepCopy() *IntegrationProfileBuildSpec { + if in == nil { + return nil + } + out := new(IntegrationProfileBuildSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntegrationProfileCondition) DeepCopyInto(out *IntegrationProfileCondition) { + *out = *in + in.LastUpdateTime.DeepCopyInto(&out.LastUpdateTime) + in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationProfileCondition. +func (in *IntegrationProfileCondition) DeepCopy() *IntegrationProfileCondition { + if in == nil { + return nil + } + out := new(IntegrationProfileCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntegrationProfileKameletSpec) DeepCopyInto(out *IntegrationProfileKameletSpec) { + *out = *in + if in.Repositories != nil { + in, out := &in.Repositories, &out.Repositories + *out = make([]KameletRepositorySpec, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationProfileKameletSpec. +func (in *IntegrationProfileKameletSpec) DeepCopy() *IntegrationProfileKameletSpec { + if in == nil { + return nil + } + out := new(IntegrationProfileKameletSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntegrationProfileList) DeepCopyInto(out *IntegrationProfileList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]IntegrationProfile, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationProfileList. +func (in *IntegrationProfileList) DeepCopy() *IntegrationProfileList { + if in == nil { + return nil + } + out := new(IntegrationProfileList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *IntegrationProfileList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntegrationProfileSpec) DeepCopyInto(out *IntegrationProfileSpec) { + *out = *in + in.Build.DeepCopyInto(&out.Build) + in.Traits.DeepCopyInto(&out.Traits) + in.Kamelet.DeepCopyInto(&out.Kamelet) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationProfileSpec. +func (in *IntegrationProfileSpec) DeepCopy() *IntegrationProfileSpec { + if in == nil { + return nil + } + out := new(IntegrationProfileSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IntegrationProfileStatus) DeepCopyInto(out *IntegrationProfileStatus) { + *out = *in + in.IntegrationProfileSpec.DeepCopyInto(&out.IntegrationProfileSpec) + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]IntegrationProfileCondition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IntegrationProfileStatus. +func (in *IntegrationProfileStatus) DeepCopy() *IntegrationProfileStatus { + if in == nil { + return nil + } + out := new(IntegrationProfileStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IntegrationSpec) DeepCopyInto(out *IntegrationSpec) { *out = *in diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationprofile.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofile.go new file mode 100644 index 0000000000..ccf9672bce --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofile.go @@ -0,0 +1,220 @@ +/* +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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// IntegrationProfileApplyConfiguration represents an declarative configuration of the IntegrationProfile type for use +// with apply. +type IntegrationProfileApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *IntegrationProfileSpecApplyConfiguration `json:"spec,omitempty"` + Status *IntegrationProfileStatusApplyConfiguration `json:"status,omitempty"` +} + +// IntegrationProfile constructs an declarative configuration of the IntegrationProfile type for use with +// apply. +func IntegrationProfile(name, namespace string) *IntegrationProfileApplyConfiguration { + b := &IntegrationProfileApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("IntegrationProfile") + b.WithAPIVersion("camel.apache.org/v1") + return b +} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithKind(value string) *IntegrationProfileApplyConfiguration { + b.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithAPIVersion(value string) *IntegrationProfileApplyConfiguration { + b.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithName(value string) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithGenerateName(value string) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithNamespace(value string) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithUID(value types.UID) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithResourceVersion(value string) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithGeneration(value int64) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithCreationTimestamp(value metav1.Time) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *IntegrationProfileApplyConfiguration) WithLabels(entries map[string]string) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Labels == nil && len(entries) > 0 { + b.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *IntegrationProfileApplyConfiguration) WithAnnotations(entries map[string]string) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.Annotations == nil && len(entries) > 0 { + b.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *IntegrationProfileApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.OwnerReferences = append(b.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *IntegrationProfileApplyConfiguration) WithFinalizers(values ...string) *IntegrationProfileApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.Finalizers = append(b.Finalizers, values[i]) + } + return b +} + +func (b *IntegrationProfileApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithSpec(value *IntegrationProfileSpecApplyConfiguration) *IntegrationProfileApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *IntegrationProfileApplyConfiguration) WithStatus(value *IntegrationProfileStatusApplyConfiguration) *IntegrationProfileApplyConfiguration { + b.Status = value + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilebuildspec.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilebuildspec.go new file mode 100644 index 0000000000..419d61e882 --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilebuildspec.go @@ -0,0 +1,90 @@ +/* +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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// IntegrationProfileBuildSpecApplyConfiguration represents an declarative configuration of the IntegrationProfileBuildSpec type for use +// with apply. +type IntegrationProfileBuildSpecApplyConfiguration struct { + RuntimeVersion *string `json:"runtimeVersion,omitempty"` + RuntimeProvider *v1.RuntimeProvider `json:"runtimeProvider,omitempty"` + BaseImage *string `json:"baseImage,omitempty"` + Registry *RegistrySpecApplyConfiguration `json:"registry,omitempty"` + Timeout *metav1.Duration `json:"timeout,omitempty"` + Maven *MavenSpecApplyConfiguration `json:"maven,omitempty"` +} + +// IntegrationProfileBuildSpecApplyConfiguration constructs an declarative configuration of the IntegrationProfileBuildSpec type for use with +// apply. +func IntegrationProfileBuildSpec() *IntegrationProfileBuildSpecApplyConfiguration { + return &IntegrationProfileBuildSpecApplyConfiguration{} +} + +// WithRuntimeVersion sets the RuntimeVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RuntimeVersion field is set to the value of the last call. +func (b *IntegrationProfileBuildSpecApplyConfiguration) WithRuntimeVersion(value string) *IntegrationProfileBuildSpecApplyConfiguration { + b.RuntimeVersion = &value + return b +} + +// WithRuntimeProvider sets the RuntimeProvider field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the RuntimeProvider field is set to the value of the last call. +func (b *IntegrationProfileBuildSpecApplyConfiguration) WithRuntimeProvider(value v1.RuntimeProvider) *IntegrationProfileBuildSpecApplyConfiguration { + b.RuntimeProvider = &value + return b +} + +// WithBaseImage sets the BaseImage field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the BaseImage field is set to the value of the last call. +func (b *IntegrationProfileBuildSpecApplyConfiguration) WithBaseImage(value string) *IntegrationProfileBuildSpecApplyConfiguration { + b.BaseImage = &value + return b +} + +// WithRegistry sets the Registry field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Registry field is set to the value of the last call. +func (b *IntegrationProfileBuildSpecApplyConfiguration) WithRegistry(value *RegistrySpecApplyConfiguration) *IntegrationProfileBuildSpecApplyConfiguration { + b.Registry = value + return b +} + +// WithTimeout sets the Timeout field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Timeout field is set to the value of the last call. +func (b *IntegrationProfileBuildSpecApplyConfiguration) WithTimeout(value metav1.Duration) *IntegrationProfileBuildSpecApplyConfiguration { + b.Timeout = &value + return b +} + +// WithMaven sets the Maven field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Maven field is set to the value of the last call. +func (b *IntegrationProfileBuildSpecApplyConfiguration) WithMaven(value *MavenSpecApplyConfiguration) *IntegrationProfileBuildSpecApplyConfiguration { + b.Maven = value + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilecondition.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilecondition.go new file mode 100644 index 0000000000..d6c3774c51 --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilecondition.go @@ -0,0 +1,91 @@ +/* +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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// IntegrationProfileConditionApplyConfiguration represents an declarative configuration of the IntegrationProfileCondition type for use +// with apply. +type IntegrationProfileConditionApplyConfiguration struct { + Type *v1.IntegrationProfileConditionType `json:"type,omitempty"` + Status *corev1.ConditionStatus `json:"status,omitempty"` + LastUpdateTime *metav1.Time `json:"lastUpdateTime,omitempty"` + LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"` + Reason *string `json:"reason,omitempty"` + Message *string `json:"message,omitempty"` +} + +// IntegrationProfileConditionApplyConfiguration constructs an declarative configuration of the IntegrationProfileCondition type for use with +// apply. +func IntegrationProfileCondition() *IntegrationProfileConditionApplyConfiguration { + return &IntegrationProfileConditionApplyConfiguration{} +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *IntegrationProfileConditionApplyConfiguration) WithType(value v1.IntegrationProfileConditionType) *IntegrationProfileConditionApplyConfiguration { + b.Type = &value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *IntegrationProfileConditionApplyConfiguration) WithStatus(value corev1.ConditionStatus) *IntegrationProfileConditionApplyConfiguration { + b.Status = &value + return b +} + +// WithLastUpdateTime sets the LastUpdateTime field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LastUpdateTime field is set to the value of the last call. +func (b *IntegrationProfileConditionApplyConfiguration) WithLastUpdateTime(value metav1.Time) *IntegrationProfileConditionApplyConfiguration { + b.LastUpdateTime = &value + return b +} + +// WithLastTransitionTime sets the LastTransitionTime field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the LastTransitionTime field is set to the value of the last call. +func (b *IntegrationProfileConditionApplyConfiguration) WithLastTransitionTime(value metav1.Time) *IntegrationProfileConditionApplyConfiguration { + b.LastTransitionTime = &value + return b +} + +// WithReason sets the Reason field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Reason field is set to the value of the last call. +func (b *IntegrationProfileConditionApplyConfiguration) WithReason(value string) *IntegrationProfileConditionApplyConfiguration { + b.Reason = &value + return b +} + +// WithMessage sets the Message field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Message field is set to the value of the last call. +func (b *IntegrationProfileConditionApplyConfiguration) WithMessage(value string) *IntegrationProfileConditionApplyConfiguration { + b.Message = &value + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilekameletspec.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilekameletspec.go new file mode 100644 index 0000000000..b8f1ffaa82 --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilekameletspec.go @@ -0,0 +1,45 @@ +/* +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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// IntegrationProfileKameletSpecApplyConfiguration represents an declarative configuration of the IntegrationProfileKameletSpec type for use +// with apply. +type IntegrationProfileKameletSpecApplyConfiguration struct { + Repositories []KameletRepositorySpecApplyConfiguration `json:"repositories,omitempty"` +} + +// IntegrationProfileKameletSpecApplyConfiguration constructs an declarative configuration of the IntegrationProfileKameletSpec type for use with +// apply. +func IntegrationProfileKameletSpec() *IntegrationProfileKameletSpecApplyConfiguration { + return &IntegrationProfileKameletSpecApplyConfiguration{} +} + +// WithRepositories adds the given value to the Repositories field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Repositories field. +func (b *IntegrationProfileKameletSpecApplyConfiguration) WithRepositories(values ...*KameletRepositorySpecApplyConfiguration) *IntegrationProfileKameletSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithRepositories") + } + b.Repositories = append(b.Repositories, *values[i]) + } + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilespec.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilespec.go new file mode 100644 index 0000000000..cb8b1dfe99 --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilespec.go @@ -0,0 +1,58 @@ +/* +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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// IntegrationProfileSpecApplyConfiguration represents an declarative configuration of the IntegrationProfileSpec type for use +// with apply. +type IntegrationProfileSpecApplyConfiguration struct { + Build *IntegrationProfileBuildSpecApplyConfiguration `json:"build,omitempty"` + Traits *TraitsApplyConfiguration `json:"traits,omitempty"` + Kamelet *IntegrationProfileKameletSpecApplyConfiguration `json:"kamelet,omitempty"` +} + +// IntegrationProfileSpecApplyConfiguration constructs an declarative configuration of the IntegrationProfileSpec type for use with +// apply. +func IntegrationProfileSpec() *IntegrationProfileSpecApplyConfiguration { + return &IntegrationProfileSpecApplyConfiguration{} +} + +// WithBuild sets the Build field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Build field is set to the value of the last call. +func (b *IntegrationProfileSpecApplyConfiguration) WithBuild(value *IntegrationProfileBuildSpecApplyConfiguration) *IntegrationProfileSpecApplyConfiguration { + b.Build = value + return b +} + +// WithTraits sets the Traits field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Traits field is set to the value of the last call. +func (b *IntegrationProfileSpecApplyConfiguration) WithTraits(value *TraitsApplyConfiguration) *IntegrationProfileSpecApplyConfiguration { + b.Traits = value + return b +} + +// WithKamelet sets the Kamelet field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kamelet field is set to the value of the last call. +func (b *IntegrationProfileSpecApplyConfiguration) WithKamelet(value *IntegrationProfileKameletSpecApplyConfiguration) *IntegrationProfileSpecApplyConfiguration { + b.Kamelet = value + return b +} diff --git a/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilestatus.go b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilestatus.go new file mode 100644 index 0000000000..025643588f --- /dev/null +++ b/pkg/client/camel/applyconfiguration/camel/v1/integrationprofilestatus.go @@ -0,0 +1,92 @@ +/* +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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" +) + +// IntegrationProfileStatusApplyConfiguration represents an declarative configuration of the IntegrationProfileStatus type for use +// with apply. +type IntegrationProfileStatusApplyConfiguration struct { + IntegrationProfileSpecApplyConfiguration `json:",inline"` + ObservedGeneration *int64 `json:"observedGeneration,omitempty"` + Phase *camelv1.IntegrationProfilePhase `json:"phase,omitempty"` + Conditions []IntegrationProfileConditionApplyConfiguration `json:"conditions,omitempty"` +} + +// IntegrationProfileStatusApplyConfiguration constructs an declarative configuration of the IntegrationProfileStatus type for use with +// apply. +func IntegrationProfileStatus() *IntegrationProfileStatusApplyConfiguration { + return &IntegrationProfileStatusApplyConfiguration{} +} + +// WithBuild sets the Build field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Build field is set to the value of the last call. +func (b *IntegrationProfileStatusApplyConfiguration) WithBuild(value *IntegrationProfileBuildSpecApplyConfiguration) *IntegrationProfileStatusApplyConfiguration { + b.Build = value + return b +} + +// WithTraits sets the Traits field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Traits field is set to the value of the last call. +func (b *IntegrationProfileStatusApplyConfiguration) WithTraits(value *TraitsApplyConfiguration) *IntegrationProfileStatusApplyConfiguration { + b.Traits = value + return b +} + +// WithKamelet sets the Kamelet field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kamelet field is set to the value of the last call. +func (b *IntegrationProfileStatusApplyConfiguration) WithKamelet(value *IntegrationProfileKameletSpecApplyConfiguration) *IntegrationProfileStatusApplyConfiguration { + b.Kamelet = value + return b +} + +// WithObservedGeneration sets the ObservedGeneration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ObservedGeneration field is set to the value of the last call. +func (b *IntegrationProfileStatusApplyConfiguration) WithObservedGeneration(value int64) *IntegrationProfileStatusApplyConfiguration { + b.ObservedGeneration = &value + return b +} + +// WithPhase sets the Phase field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Phase field is set to the value of the last call. +func (b *IntegrationProfileStatusApplyConfiguration) WithPhase(value camelv1.IntegrationProfilePhase) *IntegrationProfileStatusApplyConfiguration { + b.Phase = &value + return b +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *IntegrationProfileStatusApplyConfiguration) WithConditions(values ...*IntegrationProfileConditionApplyConfiguration) *IntegrationProfileStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} diff --git a/pkg/client/camel/applyconfiguration/utils.go b/pkg/client/camel/applyconfiguration/utils.go index 3c11cd190f..737a3d5ebc 100644 --- a/pkg/client/camel/applyconfiguration/utils.go +++ b/pkg/client/camel/applyconfiguration/utils.go @@ -130,6 +130,18 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &camelv1.IntegrationPlatformSpecApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("IntegrationPlatformStatus"): return &camelv1.IntegrationPlatformStatusApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("IntegrationProfile"): + return &camelv1.IntegrationProfileApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("IntegrationProfileBuildSpec"): + return &camelv1.IntegrationProfileBuildSpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("IntegrationProfileCondition"): + return &camelv1.IntegrationProfileConditionApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("IntegrationProfileKameletSpec"): + return &camelv1.IntegrationProfileKameletSpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("IntegrationProfileSpec"): + return &camelv1.IntegrationProfileSpecApplyConfiguration{} + case v1.SchemeGroupVersion.WithKind("IntegrationProfileStatus"): + return &camelv1.IntegrationProfileStatusApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("IntegrationSpec"): return &camelv1.IntegrationSpecApplyConfiguration{} case v1.SchemeGroupVersion.WithKind("IntegrationStatus"): diff --git a/pkg/client/camel/clientset/versioned/typed/camel/v1/camel_client.go b/pkg/client/camel/clientset/versioned/typed/camel/v1/camel_client.go index 1c6e7958e8..9e9be1e1d5 100644 --- a/pkg/client/camel/clientset/versioned/typed/camel/v1/camel_client.go +++ b/pkg/client/camel/clientset/versioned/typed/camel/v1/camel_client.go @@ -34,6 +34,7 @@ type CamelV1Interface interface { IntegrationsGetter IntegrationKitsGetter IntegrationPlatformsGetter + IntegrationProfilesGetter KameletsGetter PipesGetter } @@ -63,6 +64,10 @@ func (c *CamelV1Client) IntegrationPlatforms(namespace string) IntegrationPlatfo return newIntegrationPlatforms(c, namespace) } +func (c *CamelV1Client) IntegrationProfiles(namespace string) IntegrationProfileInterface { + return newIntegrationProfiles(c, namespace) +} + func (c *CamelV1Client) Kamelets(namespace string) KameletInterface { return newKamelets(c, namespace) } diff --git a/pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_camel_client.go b/pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_camel_client.go index 4165fa26bd..435e32b17f 100644 --- a/pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_camel_client.go +++ b/pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_camel_client.go @@ -49,6 +49,10 @@ func (c *FakeCamelV1) IntegrationPlatforms(namespace string) v1.IntegrationPlatf return &FakeIntegrationPlatforms{c, namespace} } +func (c *FakeCamelV1) IntegrationProfiles(namespace string) v1.IntegrationProfileInterface { + return &FakeIntegrationProfiles{c, namespace} +} + func (c *FakeCamelV1) Kamelets(namespace string) v1.KameletInterface { return &FakeKamelets{c, namespace} } diff --git a/pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_integrationprofile.go b/pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_integrationprofile.go new file mode 100644 index 0000000000..cbc95f6d44 --- /dev/null +++ b/pkg/client/camel/clientset/versioned/typed/camel/v1/fake/fake_integrationprofile.go @@ -0,0 +1,190 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + json "encoding/json" + "fmt" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + camelv1 "github.com/apache/camel-k/v2/pkg/client/camel/applyconfiguration/camel/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeIntegrationProfiles implements IntegrationProfileInterface +type FakeIntegrationProfiles struct { + Fake *FakeCamelV1 + ns string +} + +var integrationprofilesResource = v1.SchemeGroupVersion.WithResource("integrationprofiles") + +var integrationprofilesKind = v1.SchemeGroupVersion.WithKind("IntegrationProfile") + +// Get takes name of the integrationProfile, and returns the corresponding integrationProfile object, and an error if there is any. +func (c *FakeIntegrationProfiles) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.IntegrationProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(integrationprofilesResource, c.ns, name), &v1.IntegrationProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.IntegrationProfile), err +} + +// List takes label and field selectors, and returns the list of IntegrationProfiles that match those selectors. +func (c *FakeIntegrationProfiles) List(ctx context.Context, opts metav1.ListOptions) (result *v1.IntegrationProfileList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(integrationprofilesResource, integrationprofilesKind, c.ns, opts), &v1.IntegrationProfileList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1.IntegrationProfileList{ListMeta: obj.(*v1.IntegrationProfileList).ListMeta} + for _, item := range obj.(*v1.IntegrationProfileList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested integrationProfiles. +func (c *FakeIntegrationProfiles) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(integrationprofilesResource, c.ns, opts)) + +} + +// Create takes the representation of a integrationProfile and creates it. Returns the server's representation of the integrationProfile, and an error, if there is any. +func (c *FakeIntegrationProfiles) Create(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.CreateOptions) (result *v1.IntegrationProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(integrationprofilesResource, c.ns, integrationProfile), &v1.IntegrationProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.IntegrationProfile), err +} + +// Update takes the representation of a integrationProfile and updates it. Returns the server's representation of the integrationProfile, and an error, if there is any. +func (c *FakeIntegrationProfiles) Update(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.UpdateOptions) (result *v1.IntegrationProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(integrationprofilesResource, c.ns, integrationProfile), &v1.IntegrationProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.IntegrationProfile), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeIntegrationProfiles) UpdateStatus(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.UpdateOptions) (*v1.IntegrationProfile, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(integrationprofilesResource, "status", c.ns, integrationProfile), &v1.IntegrationProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.IntegrationProfile), err +} + +// Delete takes name of the integrationProfile and deletes it. Returns an error if one occurs. +func (c *FakeIntegrationProfiles) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(integrationprofilesResource, c.ns, name, opts), &v1.IntegrationProfile{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeIntegrationProfiles) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + action := testing.NewDeleteCollectionAction(integrationprofilesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1.IntegrationProfileList{}) + return err +} + +// Patch applies the patch and returns the patched integrationProfile. +func (c *FakeIntegrationProfiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.IntegrationProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(integrationprofilesResource, c.ns, name, pt, data, subresources...), &v1.IntegrationProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.IntegrationProfile), err +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied integrationProfile. +func (c *FakeIntegrationProfiles) Apply(ctx context.Context, integrationProfile *camelv1.IntegrationProfileApplyConfiguration, opts metav1.ApplyOptions) (result *v1.IntegrationProfile, err error) { + if integrationProfile == nil { + return nil, fmt.Errorf("integrationProfile provided to Apply must not be nil") + } + data, err := json.Marshal(integrationProfile) + if err != nil { + return nil, err + } + name := integrationProfile.Name + if name == nil { + return nil, fmt.Errorf("integrationProfile.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(integrationprofilesResource, c.ns, *name, types.ApplyPatchType, data), &v1.IntegrationProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.IntegrationProfile), err +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *FakeIntegrationProfiles) ApplyStatus(ctx context.Context, integrationProfile *camelv1.IntegrationProfileApplyConfiguration, opts metav1.ApplyOptions) (result *v1.IntegrationProfile, err error) { + if integrationProfile == nil { + return nil, fmt.Errorf("integrationProfile provided to Apply must not be nil") + } + data, err := json.Marshal(integrationProfile) + if err != nil { + return nil, err + } + name := integrationProfile.Name + if name == nil { + return nil, fmt.Errorf("integrationProfile.Name must be provided to Apply") + } + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(integrationprofilesResource, c.ns, *name, types.ApplyPatchType, data, "status"), &v1.IntegrationProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1.IntegrationProfile), err +} diff --git a/pkg/client/camel/clientset/versioned/typed/camel/v1/generated_expansion.go b/pkg/client/camel/clientset/versioned/typed/camel/v1/generated_expansion.go index f9c19c2cd5..166aedeec0 100644 --- a/pkg/client/camel/clientset/versioned/typed/camel/v1/generated_expansion.go +++ b/pkg/client/camel/clientset/versioned/typed/camel/v1/generated_expansion.go @@ -29,6 +29,8 @@ type IntegrationKitExpansion interface{} type IntegrationPlatformExpansion interface{} +type IntegrationProfileExpansion interface{} + type KameletExpansion interface{} type PipeExpansion interface{} diff --git a/pkg/client/camel/clientset/versioned/typed/camel/v1/integrationprofile.go b/pkg/client/camel/clientset/versioned/typed/camel/v1/integrationprofile.go new file mode 100644 index 0000000000..3420308692 --- /dev/null +++ b/pkg/client/camel/clientset/versioned/typed/camel/v1/integrationprofile.go @@ -0,0 +1,257 @@ +/* +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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + json "encoding/json" + "fmt" + "time" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + camelv1 "github.com/apache/camel-k/v2/pkg/client/camel/applyconfiguration/camel/v1" + scheme "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned/scheme" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// IntegrationProfilesGetter has a method to return a IntegrationProfileInterface. +// A group's client should implement this interface. +type IntegrationProfilesGetter interface { + IntegrationProfiles(namespace string) IntegrationProfileInterface +} + +// IntegrationProfileInterface has methods to work with IntegrationProfile resources. +type IntegrationProfileInterface interface { + Create(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.CreateOptions) (*v1.IntegrationProfile, error) + Update(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.UpdateOptions) (*v1.IntegrationProfile, error) + UpdateStatus(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.UpdateOptions) (*v1.IntegrationProfile, error) + Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error + Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.IntegrationProfile, error) + List(ctx context.Context, opts metav1.ListOptions) (*v1.IntegrationProfileList, error) + Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.IntegrationProfile, err error) + Apply(ctx context.Context, integrationProfile *camelv1.IntegrationProfileApplyConfiguration, opts metav1.ApplyOptions) (result *v1.IntegrationProfile, err error) + ApplyStatus(ctx context.Context, integrationProfile *camelv1.IntegrationProfileApplyConfiguration, opts metav1.ApplyOptions) (result *v1.IntegrationProfile, err error) + IntegrationProfileExpansion +} + +// integrationProfiles implements IntegrationProfileInterface +type integrationProfiles struct { + client rest.Interface + ns string +} + +// newIntegrationProfiles returns a IntegrationProfiles +func newIntegrationProfiles(c *CamelV1Client, namespace string) *integrationProfiles { + return &integrationProfiles{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the integrationProfile, and returns the corresponding integrationProfile object, and an error if there is any. +func (c *integrationProfiles) Get(ctx context.Context, name string, options metav1.GetOptions) (result *v1.IntegrationProfile, err error) { + result = &v1.IntegrationProfile{} + err = c.client.Get(). + Namespace(c.ns). + Resource("integrationprofiles"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of IntegrationProfiles that match those selectors. +func (c *integrationProfiles) List(ctx context.Context, opts metav1.ListOptions) (result *v1.IntegrationProfileList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1.IntegrationProfileList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("integrationprofiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested integrationProfiles. +func (c *integrationProfiles) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("integrationprofiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a integrationProfile and creates it. Returns the server's representation of the integrationProfile, and an error, if there is any. +func (c *integrationProfiles) Create(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.CreateOptions) (result *v1.IntegrationProfile, err error) { + result = &v1.IntegrationProfile{} + err = c.client.Post(). + Namespace(c.ns). + Resource("integrationprofiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(integrationProfile). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a integrationProfile and updates it. Returns the server's representation of the integrationProfile, and an error, if there is any. +func (c *integrationProfiles) Update(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.UpdateOptions) (result *v1.IntegrationProfile, err error) { + result = &v1.IntegrationProfile{} + err = c.client.Put(). + Namespace(c.ns). + Resource("integrationprofiles"). + Name(integrationProfile.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(integrationProfile). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *integrationProfiles) UpdateStatus(ctx context.Context, integrationProfile *v1.IntegrationProfile, opts metav1.UpdateOptions) (result *v1.IntegrationProfile, err error) { + result = &v1.IntegrationProfile{} + err = c.client.Put(). + Namespace(c.ns). + Resource("integrationprofiles"). + Name(integrationProfile.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(integrationProfile). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the integrationProfile and deletes it. Returns an error if one occurs. +func (c *integrationProfiles) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("integrationprofiles"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *integrationProfiles) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("integrationprofiles"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched integrationProfile. +func (c *integrationProfiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *v1.IntegrationProfile, err error) { + result = &v1.IntegrationProfile{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("integrationprofiles"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// Apply takes the given apply declarative configuration, applies it and returns the applied integrationProfile. +func (c *integrationProfiles) Apply(ctx context.Context, integrationProfile *camelv1.IntegrationProfileApplyConfiguration, opts metav1.ApplyOptions) (result *v1.IntegrationProfile, err error) { + if integrationProfile == nil { + return nil, fmt.Errorf("integrationProfile provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(integrationProfile) + if err != nil { + return nil, err + } + name := integrationProfile.Name + if name == nil { + return nil, fmt.Errorf("integrationProfile.Name must be provided to Apply") + } + result = &v1.IntegrationProfile{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("integrationprofiles"). + Name(*name). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} + +// ApplyStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). +func (c *integrationProfiles) ApplyStatus(ctx context.Context, integrationProfile *camelv1.IntegrationProfileApplyConfiguration, opts metav1.ApplyOptions) (result *v1.IntegrationProfile, err error) { + if integrationProfile == nil { + return nil, fmt.Errorf("integrationProfile provided to Apply must not be nil") + } + patchOpts := opts.ToPatchOptions() + data, err := json.Marshal(integrationProfile) + if err != nil { + return nil, err + } + + name := integrationProfile.Name + if name == nil { + return nil, fmt.Errorf("integrationProfile.Name must be provided to Apply") + } + + result = &v1.IntegrationProfile{} + err = c.client.Patch(types.ApplyPatchType). + Namespace(c.ns). + Resource("integrationprofiles"). + Name(*name). + SubResource("status"). + VersionedParams(&patchOpts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/camel/informers/externalversions/camel/v1/integrationprofile.go b/pkg/client/camel/informers/externalversions/camel/v1/integrationprofile.go new file mode 100644 index 0000000000..8d3e8e8148 --- /dev/null +++ b/pkg/client/camel/informers/externalversions/camel/v1/integrationprofile.go @@ -0,0 +1,91 @@ +/* +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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1 + +import ( + "context" + time "time" + + camelv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + versioned "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned" + internalinterfaces "github.com/apache/camel-k/v2/pkg/client/camel/informers/externalversions/internalinterfaces" + v1 "github.com/apache/camel-k/v2/pkg/client/camel/listers/camel/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// IntegrationProfileInformer provides access to a shared informer and lister for +// IntegrationProfiles. +type IntegrationProfileInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1.IntegrationProfileLister +} + +type integrationProfileInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewIntegrationProfileInformer constructs a new informer for IntegrationProfile type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewIntegrationProfileInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredIntegrationProfileInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredIntegrationProfileInformer constructs a new informer for IntegrationProfile type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredIntegrationProfileInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CamelV1().IntegrationProfiles(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.CamelV1().IntegrationProfiles(namespace).Watch(context.TODO(), options) + }, + }, + &camelv1.IntegrationProfile{}, + resyncPeriod, + indexers, + ) +} + +func (f *integrationProfileInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredIntegrationProfileInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *integrationProfileInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&camelv1.IntegrationProfile{}, f.defaultInformer) +} + +func (f *integrationProfileInformer) Lister() v1.IntegrationProfileLister { + return v1.NewIntegrationProfileLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/camel/informers/externalversions/camel/v1/interface.go b/pkg/client/camel/informers/externalversions/camel/v1/interface.go index 276f7fb436..a47cb41ef9 100644 --- a/pkg/client/camel/informers/externalversions/camel/v1/interface.go +++ b/pkg/client/camel/informers/externalversions/camel/v1/interface.go @@ -35,6 +35,8 @@ type Interface interface { IntegrationKits() IntegrationKitInformer // IntegrationPlatforms returns a IntegrationPlatformInformer. IntegrationPlatforms() IntegrationPlatformInformer + // IntegrationProfiles returns a IntegrationProfileInformer. + IntegrationProfiles() IntegrationProfileInformer // Kamelets returns a KameletInformer. Kamelets() KameletInformer // Pipes returns a PipeInformer. @@ -77,6 +79,11 @@ func (v *version) IntegrationPlatforms() IntegrationPlatformInformer { return &integrationPlatformInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// IntegrationProfiles returns a IntegrationProfileInformer. +func (v *version) IntegrationProfiles() IntegrationProfileInformer { + return &integrationProfileInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // Kamelets returns a KameletInformer. func (v *version) Kamelets() KameletInformer { return &kameletInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/camel/informers/externalversions/generic.go b/pkg/client/camel/informers/externalversions/generic.go index 15d15aacd3..651e153296 100644 --- a/pkg/client/camel/informers/externalversions/generic.go +++ b/pkg/client/camel/informers/externalversions/generic.go @@ -65,6 +65,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Camel().V1().IntegrationKits().Informer()}, nil case v1.SchemeGroupVersion.WithResource("integrationplatforms"): return &genericInformer{resource: resource.GroupResource(), informer: f.Camel().V1().IntegrationPlatforms().Informer()}, nil + case v1.SchemeGroupVersion.WithResource("integrationprofiles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Camel().V1().IntegrationProfiles().Informer()}, nil case v1.SchemeGroupVersion.WithResource("kamelets"): return &genericInformer{resource: resource.GroupResource(), informer: f.Camel().V1().Kamelets().Informer()}, nil case v1.SchemeGroupVersion.WithResource("pipes"): diff --git a/pkg/client/camel/listers/camel/v1/expansion_generated.go b/pkg/client/camel/listers/camel/v1/expansion_generated.go index 8a770e83b6..f987fa3fe6 100644 --- a/pkg/client/camel/listers/camel/v1/expansion_generated.go +++ b/pkg/client/camel/listers/camel/v1/expansion_generated.go @@ -59,6 +59,14 @@ type IntegrationPlatformListerExpansion interface{} // IntegrationPlatformNamespaceLister. type IntegrationPlatformNamespaceListerExpansion interface{} +// IntegrationProfileListerExpansion allows custom methods to be added to +// IntegrationProfileLister. +type IntegrationProfileListerExpansion interface{} + +// IntegrationProfileNamespaceListerExpansion allows custom methods to be added to +// IntegrationProfileNamespaceLister. +type IntegrationProfileNamespaceListerExpansion interface{} + // KameletListerExpansion allows custom methods to be added to // KameletLister. type KameletListerExpansion interface{} diff --git a/pkg/client/camel/listers/camel/v1/integrationprofile.go b/pkg/client/camel/listers/camel/v1/integrationprofile.go new file mode 100644 index 0000000000..1dcd85d313 --- /dev/null +++ b/pkg/client/camel/listers/camel/v1/integrationprofile.go @@ -0,0 +1,100 @@ +/* +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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// IntegrationProfileLister helps list IntegrationProfiles. +// All objects returned here must be treated as read-only. +type IntegrationProfileLister interface { + // List lists all IntegrationProfiles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.IntegrationProfile, err error) + // IntegrationProfiles returns an object that can list and get IntegrationProfiles. + IntegrationProfiles(namespace string) IntegrationProfileNamespaceLister + IntegrationProfileListerExpansion +} + +// integrationProfileLister implements the IntegrationProfileLister interface. +type integrationProfileLister struct { + indexer cache.Indexer +} + +// NewIntegrationProfileLister returns a new IntegrationProfileLister. +func NewIntegrationProfileLister(indexer cache.Indexer) IntegrationProfileLister { + return &integrationProfileLister{indexer: indexer} +} + +// List lists all IntegrationProfiles in the indexer. +func (s *integrationProfileLister) List(selector labels.Selector) (ret []*v1.IntegrationProfile, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1.IntegrationProfile)) + }) + return ret, err +} + +// IntegrationProfiles returns an object that can list and get IntegrationProfiles. +func (s *integrationProfileLister) IntegrationProfiles(namespace string) IntegrationProfileNamespaceLister { + return integrationProfileNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// IntegrationProfileNamespaceLister helps list and get IntegrationProfiles. +// All objects returned here must be treated as read-only. +type IntegrationProfileNamespaceLister interface { + // List lists all IntegrationProfiles in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1.IntegrationProfile, err error) + // Get retrieves the IntegrationProfile from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1.IntegrationProfile, error) + IntegrationProfileNamespaceListerExpansion +} + +// integrationProfileNamespaceLister implements the IntegrationProfileNamespaceLister +// interface. +type integrationProfileNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all IntegrationProfiles in the indexer for a given namespace. +func (s integrationProfileNamespaceLister) List(selector labels.Selector) (ret []*v1.IntegrationProfile, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1.IntegrationProfile)) + }) + return ret, err +} + +// Get retrieves the IntegrationProfile from the indexer for a given namespace and name. +func (s integrationProfileNamespaceLister) Get(name string) (*v1.IntegrationProfile, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1.Resource("integrationprofile"), name) + } + return obj.(*v1.IntegrationProfile), nil +} diff --git a/pkg/cmd/kamelet_add_repo.go b/pkg/cmd/kamelet_add_repo.go index e72b4d074b..870955cd73 100644 --- a/pkg/cmd/kamelet_add_repo.go +++ b/pkg/cmd/kamelet_add_repo.go @@ -52,7 +52,7 @@ func newKameletAddRepoCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *kame }, } - cmd.Flags().StringP("operator-id", "x", "", "Id of the Operator to update. If not set, the active primary Integration Platform is updated.") + cmd.Flags().StringP("operator-id", "x", "", "Id of the Operator to update. If not set, the default active Integration Platform is updated.") return &cmd, &options } @@ -118,9 +118,9 @@ func (o *kameletUpdateRepoCommandOptions) getIntegrationPlatform(cmd *cobra.Comm return &platform, nil } -// findIntegrationPlatform gives the primary integration platform that could be found in the provided namespace. +// findIntegrationPlatform gives the integration platform that could be found in the provided namespace. func (o *kameletUpdateRepoCommandOptions) findIntegrationPlatform(cmd *cobra.Command, c client.Client) (*v1.IntegrationPlatform, error) { - platforms, err := platformutil.ListPrimaryPlatforms(o.Context, c, o.Namespace) + platforms, err := platformutil.ListPlatforms(o.Context, c, o.Namespace) if err != nil { return nil, err } @@ -130,7 +130,7 @@ func (o *kameletUpdateRepoCommandOptions) findIntegrationPlatform(cmd *cobra.Com return &p, nil } } - fmt.Fprintf(cmd.ErrOrStderr(), "Warning: No active primary IntegrationPlatform could be found in namespace %q\n", o.Namespace) + fmt.Fprintf(cmd.ErrOrStderr(), "Warning: No active IntegrationPlatform could be found in namespace %q\n", o.Namespace) return nil, nil } diff --git a/pkg/cmd/kamelet_remove_repo.go b/pkg/cmd/kamelet_remove_repo.go index 4ee189042c..f3de5e0837 100644 --- a/pkg/cmd/kamelet_remove_repo.go +++ b/pkg/cmd/kamelet_remove_repo.go @@ -45,7 +45,7 @@ func newKameletRemoveRepoCmd(rootCmdOptions *RootCmdOptions) (*cobra.Command, *k }, } - cmd.Flags().StringP("operator-id", "x", "", "Id of the Operator to update. If not set, the active primary Integration Platform is updated.") + cmd.Flags().StringP("operator-id", "x", "", "Id of the Operator to update. If not set, the default active Integration Platform is updated.") return &cmd, &options } diff --git a/pkg/cmd/reset.go b/pkg/cmd/reset.go index f09062622e..1e6ece75d2 100644 --- a/pkg/cmd/reset.go +++ b/pkg/cmd/reset.go @@ -37,7 +37,7 @@ func newCmdReset(rootCmdOptions *RootCmdOptions) (*cobra.Command, *resetCmdOptio cmd := cobra.Command{ Use: "reset", Short: "Reset the Camel K installation", - Long: `Reset the Camel K installation by deleting everything except current platform configuration.`, + Long: `Reset the Camel K installation by deleting everything except current integration profile.`, PreRunE: decode(&options), Run: options.reset, } diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 589565ce7c..43968d0266 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -112,6 +112,7 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions) cmd.Flags().Bool("use-flows", true, "Write yaml sources as Flow objects in the integration custom resource") cmd.Flags().StringP("operator-id", "x", "camel-k", "Operator id selected to manage this integration.") cmd.Flags().String("profile", "", "Trait profile used for deployment") + cmd.Flags().String("integration-profile", "", "Integration profile used for deployment") cmd.Flags().StringArrayP("trait", "t", nil, "Configure a trait. E.g. \"-t service.enabled=false\"") cmd.Flags().StringP("output", "o", "", "Output format. One of: json|yaml") cmd.Flags().Bool("compression", false, "Enable storage of sources and resources as a compressed binary blobs") @@ -134,38 +135,39 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions) } type runCmdOptions struct { - *RootCmdOptions `json:"-"` - Compression bool `mapstructure:"compression" yaml:",omitempty"` - Wait bool `mapstructure:"wait" yaml:",omitempty"` - Logs bool `mapstructure:"logs" yaml:",omitempty"` - Sync bool `mapstructure:"sync" yaml:",omitempty"` - Dev bool `mapstructure:"dev" yaml:",omitempty"` - UseFlows bool `mapstructure:"use-flows" yaml:",omitempty"` - Save bool `mapstructure:"save" yaml:",omitempty" kamel:"omitsave"` - IntegrationKit string `mapstructure:"kit" yaml:",omitempty"` - IntegrationName string `mapstructure:"name" yaml:",omitempty"` - ContainerImage string `mapstructure:"image" yaml:",omitempty"` - Profile string `mapstructure:"profile" yaml:",omitempty"` - OperatorID string `mapstructure:"operator-id" yaml:",omitempty"` - OutputFormat string `mapstructure:"output" yaml:",omitempty"` - PodTemplate string `mapstructure:"pod-template" yaml:",omitempty"` - ServiceAccount string `mapstructure:"service-account" yaml:",omitempty"` - Connects []string `mapstructure:"connects" yaml:",omitempty"` - Resources []string `mapstructure:"resources" yaml:",omitempty"` - OpenAPIs []string `mapstructure:"open-apis" yaml:",omitempty"` - Dependencies []string `mapstructure:"dependencies" yaml:",omitempty"` - Properties []string `mapstructure:"properties" yaml:",omitempty"` - BuildProperties []string `mapstructure:"build-properties" yaml:",omitempty"` - Configs []string `mapstructure:"configs" yaml:",omitempty"` - Repositories []string `mapstructure:"maven-repositories" yaml:",omitempty"` - Traits []string `mapstructure:"traits" yaml:",omitempty"` - Volumes []string `mapstructure:"volumes" yaml:",omitempty"` - EnvVars []string `mapstructure:"envs" yaml:",omitempty"` - Labels []string `mapstructure:"labels" yaml:",omitempty"` - Annotations []string `mapstructure:"annotations" yaml:",omitempty"` - Sources []string `mapstructure:"sources" yaml:",omitempty"` - RegistryOptions url.Values - Force bool `mapstructure:"force" yaml:",omitempty"` + *RootCmdOptions `json:"-"` + Compression bool `mapstructure:"compression" yaml:",omitempty"` + Wait bool `mapstructure:"wait" yaml:",omitempty"` + Logs bool `mapstructure:"logs" yaml:",omitempty"` + Sync bool `mapstructure:"sync" yaml:",omitempty"` + Dev bool `mapstructure:"dev" yaml:",omitempty"` + UseFlows bool `mapstructure:"use-flows" yaml:",omitempty"` + Save bool `mapstructure:"save" yaml:",omitempty" kamel:"omitsave"` + IntegrationKit string `mapstructure:"kit" yaml:",omitempty"` + IntegrationName string `mapstructure:"name" yaml:",omitempty"` + ContainerImage string `mapstructure:"image" yaml:",omitempty"` + Profile string `mapstructure:"profile" yaml:",omitempty"` + IntegrationProfile string `mapstructure:"integration-profile" yaml:",omitempty"` + OperatorID string `mapstructure:"operator-id" yaml:",omitempty"` + OutputFormat string `mapstructure:"output" yaml:",omitempty"` + PodTemplate string `mapstructure:"pod-template" yaml:",omitempty"` + ServiceAccount string `mapstructure:"service-account" yaml:",omitempty"` + Connects []string `mapstructure:"connects" yaml:",omitempty"` + Resources []string `mapstructure:"resources" yaml:",omitempty"` + OpenAPIs []string `mapstructure:"open-apis" yaml:",omitempty"` + Dependencies []string `mapstructure:"dependencies" yaml:",omitempty"` + Properties []string `mapstructure:"properties" yaml:",omitempty"` + BuildProperties []string `mapstructure:"build-properties" yaml:",omitempty"` + Configs []string `mapstructure:"configs" yaml:",omitempty"` + Repositories []string `mapstructure:"maven-repositories" yaml:",omitempty"` + Traits []string `mapstructure:"traits" yaml:",omitempty"` + Volumes []string `mapstructure:"volumes" yaml:",omitempty"` + EnvVars []string `mapstructure:"envs" yaml:",omitempty"` + Labels []string `mapstructure:"labels" yaml:",omitempty"` + Annotations []string `mapstructure:"annotations" yaml:",omitempty"` + Sources []string `mapstructure:"sources" yaml:",omitempty"` + RegistryOptions url.Values + Force bool `mapstructure:"force" yaml:",omitempty"` } func (o *runCmdOptions) decode(cmd *cobra.Command, args []string) error { @@ -666,6 +668,17 @@ func (o *runCmdOptions) applyAnnotations(cmd *cobra.Command, c client.Client, it // --operator-id={id} is a syntax sugar for '--annotation camel.apache.org/operator.id={id}' it.SetOperatorID(strings.TrimSpace(o.OperatorID)) + // --integration-profile={id} is a syntax sugar for '--annotation camel.apache.org/integration-profile.id={id}' + if o.IntegrationProfile != "" { + if strings.Contains(o.IntegrationProfile, "/") { + namespacedName := strings.SplitN(o.IntegrationProfile, "/", 2) + v1.SetAnnotation(&it.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, namespacedName[0]) + v1.SetAnnotation(&it.ObjectMeta, v1.IntegrationProfileAnnotation, namespacedName[1]) + } else { + v1.SetAnnotation(&it.ObjectMeta, v1.IntegrationProfileAnnotation, o.IntegrationProfile) + } + } + for _, annotation := range o.Annotations { parts := strings.SplitN(annotation, "=", 2) if len(parts) == 2 { @@ -854,7 +867,7 @@ func (o *runCmdOptions) getPlatform(cmd *cobra.Command, c client.Client, it *v1. if !contains(o.Traits, "registry.enabled=false") { o.Traits = append(o.Traits, "registry.enabled=true") } - pl, err := platform.GetOrFindForResource(o.Context, c, it, true) + pl, err := platform.GetForResource(o.Context, c, it) if err != nil { return nil, err } diff --git a/pkg/cmd/uninstall.go b/pkg/cmd/uninstall.go index fc9815504a..eb0e5b7794 100644 --- a/pkg/cmd/uninstall.go +++ b/pkg/cmd/uninstall.go @@ -62,6 +62,7 @@ func newCmdUninstall(rootCmdOptions *RootCmdOptions) (*cobra.Command, *uninstall cmd.Flags().Bool("skip-cluster-role-bindings", true, "Do not uninstall the Camel K Cluster Role Bindings") cmd.Flags().Bool("skip-cluster-roles", true, "Do not uninstall the Camel K Cluster Roles") cmd.Flags().Bool("skip-integration-platform", false, "Do not uninstall the Camel K Integration Platform in the current namespace") + cmd.Flags().Bool("skip-integration-profile", false, "Do not uninstall the Camel K Integration Profile in the current namespace") cmd.Flags().Bool("skip-service-accounts", false, "Do not uninstall the Camel K Service Accounts in the current namespace") cmd.Flags().Bool("skip-config-maps", false, "Do not uninstall the Camel K Config Maps in the current namespace") cmd.Flags().Bool("skip-registry-secret", false, "Do not uninstall the Camel K Registry Secret in the current namespace") @@ -87,6 +88,7 @@ type uninstallCmdOptions struct { SkipClusterRoleBindings bool `mapstructure:"skip-cluster-role-bindings"` SkipClusterRoles bool `mapstructure:"skip-cluster-roles"` SkipIntegrationPlatform bool `mapstructure:"skip-integration-platform"` + SkipIntegrationProfile bool `mapstructure:"skip-integration-profile"` SkipServiceAccounts bool `mapstructure:"skip-service-accounts"` SkipConfigMaps bool `mapstructure:"skip-config-maps"` SkipRegistrySecret bool `mapstructure:"skip-registry-secret"` @@ -129,6 +131,13 @@ func (o *uninstallCmdOptions) uninstall(cmd *cobra.Command, _ []string) error { fmt.Fprintf(cmd.OutOrStdout(), "Camel K Integration Platform removed from namespace %s\n", o.Namespace) } + if !o.SkipIntegrationProfile { + if err = o.uninstallIntegrationProfile(o.Context, c); err != nil { + return err + } + fmt.Fprintf(cmd.OutOrStdout(), "Camel K Integration Profile removed from namespace %s\n", o.Namespace) + } + if err = o.uninstallNamespaceResources(o.Context, cmd, c); err != nil { return err } @@ -486,6 +495,22 @@ func (o *uninstallCmdOptions) uninstallIntegrationPlatform(ctx context.Context, return nil } +func (o *uninstallCmdOptions) uninstallIntegrationProfile(ctx context.Context, c client.Client) error { + configurations, err := c.CamelV1().IntegrationProfiles(o.Namespace).List(ctx, metav1.ListOptions{}) + if err != nil { + return err + } + + for _, configuration := range configurations.Items { + err := c.CamelV1().IntegrationProfiles(o.Namespace).Delete(ctx, configuration.GetName(), metav1.DeleteOptions{}) + if err != nil { + return err + } + } + + return nil +} + func (o *uninstallCmdOptions) uninstallConfigMaps(ctx context.Context, c client.Client) error { api := c.CoreV1() diff --git a/pkg/cmd/uninstall_test.go b/pkg/cmd/uninstall_test.go index 2c37dc55d6..e10f9f3882 100644 --- a/pkg/cmd/uninstall_test.go +++ b/pkg/cmd/uninstall_test.go @@ -57,11 +57,12 @@ func TestUninstallSkipFlags(t *testing.T) { kamelTestPostAddCommandInit(t, cmd) - _, err := test.ExecuteCommand(cmd, "uninstall", "--skip-crd", "--skip-cluster-roles", "--skip-integration-platform") + _, err := test.ExecuteCommand(cmd, "uninstall", "--skip-crd", "--skip-cluster-roles", "--skip-integration-platform", "--skip-integration-profile") assert.Nil(t, err) assert.True(t, uninstallCmdOptions.SkipCrd) assert.True(t, uninstallCmdOptions.SkipClusterRoles) assert.True(t, uninstallCmdOptions.SkipIntegrationPlatform) + assert.True(t, uninstallCmdOptions.SkipIntegrationProfile) } func TestUninstallAllFlag(t *testing.T) { @@ -76,4 +77,5 @@ func TestUninstallAllFlag(t *testing.T) { assert.True(t, uninstallCmdOptions.SkipCrd) assert.True(t, uninstallCmdOptions.SkipClusterRoles) assert.False(t, uninstallCmdOptions.SkipIntegrationPlatform) + assert.False(t, uninstallCmdOptions.SkipIntegrationProfile) } diff --git a/pkg/controller/add_integrationprofile.go b/pkg/controller/add_integrationprofile.go new file mode 100644 index 0000000000..469cf40ac6 --- /dev/null +++ b/pkg/controller/add_integrationprofile.go @@ -0,0 +1,26 @@ +/* +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 controller + +import ( + "github.com/apache/camel-k/v2/pkg/controller/integrationprofile" +) + +func init() { + addToManager = append(addToManager, integrationprofile.Add) +} diff --git a/pkg/controller/build/build_controller.go b/pkg/controller/build/build_controller.go index 20bb554bce..48dce58940 100644 --- a/pkg/controller/build/build_controller.go +++ b/pkg/controller/build/build_controller.go @@ -141,7 +141,7 @@ func (r *reconcileBuild) Reconcile(ctx context.Context, request reconcile.Reques targetLog := rlog.ForBuild(target) var actions []Action - ip, err := platform.GetOrFindForResource(ctx, r.client, &instance, true) + ip, err := platform.GetForResource(ctx, r.client, &instance) if err != nil { rlog.Error(err, "Could not find a platform bound to this Build") return reconcile.Result{}, err diff --git a/pkg/controller/catalog/initialize.go b/pkg/controller/catalog/initialize.go index 61be5e2c55..3aac6ab657 100644 --- a/pkg/controller/catalog/initialize.go +++ b/pkg/controller/catalog/initialize.go @@ -22,6 +22,7 @@ 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/defaults" corev1 "k8s.io/api/core/v1" ) @@ -45,7 +46,7 @@ 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.GetOrFindLocal(ctx, action.client, catalog.Namespace) + platform, err := platformutil.GetForName(ctx, action.client, catalog.Namespace, defaults.OperatorID()) if err != nil { return catalog, err diff --git a/pkg/controller/integration/build_kit.go b/pkg/controller/integration/build_kit.go index a2f3f4238c..6d47c00088 100644 --- a/pkg/controller/integration/build_kit.go +++ b/pkg/controller/integration/build_kit.go @@ -70,11 +70,10 @@ func (action *buildKitAction) Handle(ctx context.Context, integration *v1.Integr if err != nil { return nil, fmt.Errorf("unable to find integration kit %s/%s: %w", integration.Status.IntegrationKit.Namespace, integration.Status.IntegrationKit.Name, err) - } if kit.Labels[v1.IntegrationKitTypeLabel] == v1.IntegrationKitTypePlatform { - match, err := integrationMatches(integration, kit) + match, err := integrationMatches(ctx, action.client, integration, kit) if err != nil { return nil, fmt.Errorf("unable to match any integration kit with integration %s/%s: %w", integration.Namespace, integration.Name, err) diff --git a/pkg/controller/integration/integration_controller.go b/pkg/controller/integration/integration_controller.go index 233523a1eb..18ebcb24a8 100644 --- a/pkg/controller/integration/integration_controller.go +++ b/pkg/controller/integration/integration_controller.go @@ -125,7 +125,7 @@ func isIntegrationUpdated(it *v1.Integration, previous, next *v1.IntegrationCond } func integrationKitEnqueueRequestsFromMapFunc(ctx context.Context, c client.Client, kit *v1.IntegrationKit) []reconcile.Request { - var requests []reconcile.Request + requests := make([]reconcile.Request, 0) if kit.Status.Phase != v1.IntegrationKitPhaseReady && kit.Status.Phase != v1.IntegrationKitPhaseError { return requests } @@ -143,9 +143,14 @@ func integrationKitEnqueueRequestsFromMapFunc(ctx context.Context, c client.Clie for i := range list.Items { integration := &list.Items[i] + if integration.Status.Phase != v1.IntegrationPhaseBuildingKit && + integration.Status.Phase != v1.IntegrationPhaseRunning { + continue + } + Log.Debug("Integration Controller: Assessing integration", "integration", integration.Name, "namespace", integration.Namespace) - match, err := sameOrMatch(kit, integration) + match, err := sameOrMatch(ctx, c, kit, integration) if err != nil { Log.ForIntegration(integration).Errorf(err, "Error matching integration %q with kit %q", integration.Name, kit.Name) continue @@ -154,16 +159,13 @@ func integrationKitEnqueueRequestsFromMapFunc(ctx context.Context, c client.Clie continue } - if integration.Status.Phase == v1.IntegrationPhaseBuildingKit || - integration.Status.Phase == v1.IntegrationPhaseRunning { - log.Infof("Kit %s ready, notify integration: %s", kit.Name, integration.Name) - requests = append(requests, reconcile.Request{ - NamespacedName: types.NamespacedName{ - Namespace: integration.Namespace, - Name: integration.Name, - }, - }) - } + log.Infof("Kit %s ready, notify integration: %s", kit.Name, integration.Name) + requests = append(requests, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: integration.Namespace, + Name: integration.Name, + }, + }) } return requests @@ -269,6 +271,42 @@ func secretEnqueueRequestsFromMapFunc(ctx context.Context, c client.Client, sec return requests } +func integrationProfileEnqueueRequestsFromMapFunc(ctx context.Context, c client.Client, profile *v1.IntegrationProfile) []reconcile.Request { + var requests []reconcile.Request + + if profile.Status.Phase == v1.IntegrationProfilePhaseReady { + list := &v1.IntegrationList{} + + // Do global search in case of global operator + var opts []ctrl.ListOption + if !platform.IsCurrentOperatorGlobal() { + opts = append(opts, ctrl.InNamespace(profile.Namespace)) + } + + if err := c.List(ctx, list, opts...); err != nil { + log.Error(err, "Failed to list integrations") + return requests + } + + for i := range list.Items { + integration := list.Items[i] + if integration.Status.Phase == v1.IntegrationPhaseRunning && v1.GetIntegrationProfileAnnotation(&integration) == profile.Name { + if profileNamespace := v1.GetIntegrationProfileNamespaceAnnotation(&integration); profileNamespace == "" || profileNamespace == profile.Namespace { + log.Infof("IntegrationProfile %s changed, notify integration: %s", profile.Name, integration.Name) + requests = append(requests, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Namespace: integration.Namespace, + Name: integration.Name, + }, + }) + } + } + } + } + + return requests +} + func integrationPlatformEnqueueRequestsFromMapFunc(ctx context.Context, c client.Client, p *v1.IntegrationPlatform) []reconcile.Request { var requests []reconcile.Request @@ -367,6 +405,16 @@ func watchIntegrationResources(c client.Client, b *builder.Builder) { } return integrationPlatformEnqueueRequestsFromMapFunc(ctx, c, p) })). + // Watch for IntegrationProfile and enqueue requests for any integrations that references the profile + Watches(&v1.IntegrationProfile{}, + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a ctrl.Object) []reconcile.Request { + profile, ok := a.(*v1.IntegrationProfile) + if !ok { + log.Error(fmt.Errorf("type assertion failed: %v", a), "Failed to retrieve IntegrationProfile") + return []reconcile.Request{} + } + return integrationProfileEnqueueRequestsFromMapFunc(ctx, c, profile) + })). // Watch for Configmaps or Secret used in the Integrations for updates Watches(&corev1.ConfigMap{}, handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, a ctrl.Object) []reconcile.Request { diff --git a/pkg/controller/integration/kits.go b/pkg/controller/integration/kits.go index c4c2e69e8c..fd1a106ddf 100644 --- a/pkg/controller/integration/kits.go +++ b/pkg/controller/integration/kits.go @@ -29,6 +29,7 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" ctrl "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/apache/camel-k/v2/pkg/client" "github.com/apache/camel-k/v2/pkg/platform" "github.com/apache/camel-k/v2/pkg/trait" "github.com/apache/camel-k/v2/pkg/util" @@ -36,7 +37,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/log" ) -func lookupKitsForIntegration(ctx context.Context, c ctrl.Reader, integration *v1.Integration, options ...ctrl.ListOption) ([]v1.IntegrationKit, error) { +func lookupKitsForIntegration(ctx context.Context, c client.Client, integration *v1.Integration, options ...ctrl.ListOption) ([]v1.IntegrationKit, error) { pl, err := platform.GetForResource(ctx, c, integration) if err != nil && !k8serrors.IsNotFound(err) { return nil, err @@ -70,7 +71,7 @@ func lookupKitsForIntegration(ctx context.Context, c ctrl.Reader, integration *v kits := make([]v1.IntegrationKit, 0) for i := range list.Items { kit := &list.Items[i] - match, err := integrationMatches(integration, kit) + match, err := integrationMatches(ctx, c, integration, kit) if err != nil { return nil, err } else if !match || kit.Status.Phase == v1.IntegrationKitPhaseError { @@ -84,18 +85,18 @@ func lookupKitsForIntegration(ctx context.Context, c ctrl.Reader, integration *v // sameOrMatch returns whether the v1.IntegrationKit is the one used by the v1.Integration or if it meets the // requirements of the v1.Integration. -func sameOrMatch(kit *v1.IntegrationKit, integration *v1.Integration) (bool, error) { +func sameOrMatch(ctx context.Context, c client.Client, kit *v1.IntegrationKit, integration *v1.Integration) (bool, error) { if integration.Status.IntegrationKit != nil { if integration.Status.IntegrationKit.Namespace == kit.Namespace && integration.Status.IntegrationKit.Name == kit.Name { return true, nil } } - return integrationMatches(integration, kit) + return integrationMatches(ctx, c, integration, kit) } // integrationMatches returns whether the v1.IntegrationKit meets the requirements of the v1.Integration. -func integrationMatches(integration *v1.Integration, kit *v1.IntegrationKit) (bool, error) { +func integrationMatches(ctx context.Context, c client.Client, integration *v1.Integration, kit *v1.IntegrationKit) (bool, error) { ilog := log.ForIntegration(integration) ilog.Debug("Matching integration", "integration", integration.Name, "integration-kit", kit.Name, "namespace", integration.Namespace) @@ -114,7 +115,15 @@ func integrationMatches(integration *v1.Integration, kit *v1.IntegrationKit) (bo // A kit can be used only if it contains a subset of the traits and related configurations // declared on integration. - itc, err := trait.NewStatusTraitsOptionsForIntegration(integration) + pl, err := platform.GetForResource(ctx, c, integration) + if err != nil && !k8serrors.IsNotFound(err) { + return false, err + } + if _, err := platform.ApplyIntegrationProfile(ctx, c, pl, integration); err != nil { + return false, err + } + + itc, err := trait.NewSpecTraitsOptionsForIntegrationAndPlatform(integration, pl) if err != nil { return false, err } diff --git a/pkg/controller/integration/kits_test.go b/pkg/controller/integration/kits_test.go index c2713159c7..4e5d70907d 100644 --- a/pkg/controller/integration/kits_test.go +++ b/pkg/controller/integration/kits_test.go @@ -35,6 +35,16 @@ import ( func TestLookupKitForIntegration_DiscardKitsInError(t *testing.T) { c, err := test.NewFakeClient( + &v1.IntegrationPlatform{ + TypeMeta: metav1.TypeMeta{ + APIVersion: v1.SchemeGroupVersion.String(), + Kind: v1.IntegrationPlatformKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns", + Name: "camel-k", + }, + }, &v1.IntegrationKit{ TypeMeta: metav1.TypeMeta{ APIVersion: v1.SchemeGroupVersion.String(), @@ -112,6 +122,16 @@ func TestLookupKitForIntegration_DiscardKitsInError(t *testing.T) { func TestLookupKitForIntegration_DiscardKitsWithIncompatibleTraits(t *testing.T) { c, err := test.NewFakeClient( + &v1.IntegrationPlatform{ + TypeMeta: metav1.TypeMeta{ + APIVersion: v1.SchemeGroupVersion.String(), + Kind: v1.IntegrationPlatformKind, + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "ns", + Name: "camel-k", + }, + }, // Should be discarded because it does not contain the required traits &v1.IntegrationKit{ TypeMeta: metav1.TypeMeta{ @@ -472,7 +492,7 @@ func TestHasNotMatchingSources(t *testing.T) { } func integrationAndKitHaveSameTraits(i1 *v1.Integration, i2 *v1.IntegrationKit) (bool, error) { - itOpts, err := trait.NewStatusTraitsOptionsForIntegration(i1) + itOpts, err := trait.NewSpecTraitsOptionsForIntegration(i1) if err != nil { return false, err } diff --git a/pkg/controller/integration/monitor.go b/pkg/controller/integration/monitor.go index 048136d911..276216920e 100644 --- a/pkg/controller/integration/monitor.go +++ b/pkg/controller/integration/monitor.go @@ -70,7 +70,7 @@ func (action *monitorAction) Handle(ctx context.Context, integration *v1.Integra return action.checkDigestAndRebuild(ctx, integration, nil) } - // At that staged the Integration must have a Kit + // At this stage the Integration must have a Kit if integration.Status.IntegrationKit == nil { return nil, fmt.Errorf("no kit set on integration %s", integration.Name) } @@ -105,6 +105,7 @@ func (action *monitorAction) Handle(ctx context.Context, integration *v1.Integra if err != nil { return nil, err } + kits, err := lookupKitsForIntegration(ctx, action.client, integration, ctrl.MatchingLabelsSelector{ Selector: labels.NewSelector().Add(*withHigherPriority), }) @@ -236,11 +237,7 @@ func (action *monitorAction) checkDigestAndRebuild(ctx context.Context, integrat if hash != integration.Status.Digest { action.L.Info("Monitor: Integration needs a rebuild") - if kit != nil && - v1.GetOperatorIDAnnotation(integration) != "" && - v1.GetOperatorIDAnnotation(integration) != v1.GetOperatorIDAnnotation(kit) { - // Operator to reconcile the integration has changed. Reset integration kit - // so new operator can handle the kit reference + if isIntegrationKitResetRequired(integration, kit) { integration.SetIntegrationKit(nil) } @@ -253,6 +250,35 @@ func (action *monitorAction) checkDigestAndRebuild(ctx context.Context, integrat return nil, nil } +func isIntegrationKitResetRequired(integration *v1.Integration, kit *v1.IntegrationKit) bool { + if kit == nil { + return false + } + + if v1.GetOperatorIDAnnotation(integration) != "" && + v1.GetOperatorIDAnnotation(integration) != v1.GetOperatorIDAnnotation(kit) { + // Operator to reconcile the integration has changed. Reset integration kit + // so new operator can handle the kit reference + return true + } + + if v1.GetIntegrationProfileAnnotation(integration) != "" && + v1.GetIntegrationProfileAnnotation(integration) != v1.GetIntegrationProfileAnnotation(kit) { + // Integration profile for the integration has changed. Reset integration kit + // so new profile can be applied + return true + } + + if v1.GetIntegrationProfileNamespaceAnnotation(integration) != "" && + v1.GetIntegrationProfileNamespaceAnnotation(integration) != v1.GetIntegrationProfileNamespaceAnnotation(kit) { + // Integration profile namespace for the integration has changed. Reset integration kit + // so new profile can be applied + return true + } + + return false +} + func getIntegrationSecretsAndConfigmaps(ctx context.Context, client client.Client, integration *v1.Integration) ([]*corev1.Secret, []*corev1.ConfigMap) { configmaps := make([]*corev1.ConfigMap, 0) secrets := make([]*corev1.Secret, 0) diff --git a/pkg/controller/integrationkit/build.go b/pkg/controller/integrationkit/build.go index 1051245880..b68c63c66f 100644 --- a/pkg/controller/integrationkit/build.go +++ b/pkg/controller/integrationkit/build.go @@ -94,6 +94,15 @@ func (action *buildAction) handleBuildSubmitted(ctx context.Context, kit *v1.Int if v, ok := kit.Annotations[v1.PlatformSelectorAnnotation]; ok { annotations[v1.PlatformSelectorAnnotation] = v } + + if v, ok := kit.Annotations[v1.IntegrationProfileAnnotation]; ok { + annotations[v1.IntegrationProfileAnnotation] = v + + if v, ok := kit.Annotations[v1.IntegrationProfileNamespaceAnnotation]; ok { + annotations[v1.IntegrationProfileNamespaceAnnotation] = v + } + } + operatorID := defaults.OperatorID() if operatorID != "" { annotations[v1.OperatorIDAnnotation] = operatorID diff --git a/pkg/controller/integrationkit/integrationkit_controller.go b/pkg/controller/integrationkit/integrationkit_controller.go index 56244785f2..6c3c217455 100644 --- a/pkg/controller/integrationkit/integrationkit_controller.go +++ b/pkg/controller/integrationkit/integrationkit_controller.go @@ -155,6 +155,12 @@ func add(_ context.Context, mgr manager.Manager, r reconcile.Reconciler) error { continue } + if v, ok := kit.Annotations[v1.OperatorIDAnnotation]; ok && v != p.Name { + // kit waiting for another platform to become ready - skip here + log.Debugf("Integration kit %s is waiting for another integration platform '%s' - skip it now", kit.Name, v) + continue + } + if kit.Status.Phase == v1.IntegrationKitPhaseWaitingForPlatform { log.Infof("Platform %s ready, wake-up integration kit: %s", p.Name, kit.Name) requests = append(requests, reconcile.Request{ @@ -237,7 +243,7 @@ func (r *reconcileIntegrationKit) Reconcile(ctx context.Context, request reconci } // Platform is always local to the kit - pl, err := platform.GetOrFindLocalForResource(ctx, r.client, target, true) + pl, err := platform.GetForResource(ctx, r.client, target) if err != nil || pl.Status.Phase != v1.IntegrationPlatformPhaseReady { target.Status.Phase = v1.IntegrationKitPhaseWaitingForPlatform } else { diff --git a/pkg/controller/integrationplatform/create.go b/pkg/controller/integrationplatform/create.go index 07586cda2c..8471ca5e52 100644 --- a/pkg/controller/integrationplatform/create.go +++ b/pkg/controller/integrationplatform/create.go @@ -25,12 +25,11 @@ import ( v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/install" - platformutil "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" ) -// NewCreateAction returns a action that creates resources needed by the platform. +// NewCreateAction returns the action that creates resources needed by the platform. func NewCreateAction() Action { return &createAction{} } @@ -67,7 +66,7 @@ func (action *createAction) Handle(ctx context.Context, platform *v1.Integration } } - if !platformutil.IsSecondary(platform) && defaults.InstallDefaultKamelets() { + 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 diff --git a/pkg/controller/integrationplatform/initialize.go b/pkg/controller/integrationplatform/initialize.go index 0d766a92ad..4b68c2ff90 100644 --- a/pkg/controller/integrationplatform/initialize.go +++ b/pkg/controller/integrationplatform/initialize.go @@ -25,7 +25,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/defaults" ) -// NewInitializeAction returns a action that initializes the platform configuration when not provided by the user. +// NewInitializeAction returns the action that initializes the integration platform when not provided by the user. func NewInitializeAction() Action { return &initializeAction{} } @@ -39,28 +39,12 @@ func (action *initializeAction) Name() string { } func (action *initializeAction) CanHandle(platform *v1.IntegrationPlatform) bool { - return platform.Status.Phase == v1.IntegrationPlatformPhaseNone || platform.Status.Phase == v1.IntegrationPlatformPhaseDuplicate + return platform.Status.Phase == v1.IntegrationPlatformPhaseNone } func (action *initializeAction) Handle(ctx context.Context, platform *v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) { - duplicate, err := action.isPrimaryDuplicate(ctx, platform) - if err != nil { - return nil, err - } - if duplicate { - // another platform already present in the namespace - if platform.Status.Phase != v1.IntegrationPlatformPhaseDuplicate { - platform := platform.DeepCopy() - platform.Status.Phase = v1.IntegrationPlatformPhaseDuplicate - - return platform, nil - } - - return nil, nil - } - action.L.Info("Initializing IntegrationPlatform") - if err = platformutil.ConfigureDefaults(ctx, action.client, platform, true); err != nil { + if err := platformutil.ConfigureDefaults(ctx, action.client, platform, true); err != nil { return nil, err } platform.Status.Phase = v1.IntegrationPlatformPhaseCreating @@ -68,22 +52,3 @@ func (action *initializeAction) Handle(ctx context.Context, platform *v1.Integra return platform, nil } - -func (action *initializeAction) isPrimaryDuplicate(ctx context.Context, thisPlatform *v1.IntegrationPlatform) (bool, error) { - if platformutil.IsSecondary(thisPlatform) { - // Always reconcile secondary platforms - return false, nil - } - platforms, err := platformutil.ListPrimaryPlatforms(ctx, action.client, thisPlatform.Namespace) - if err != nil { - return false, err - } - for _, p := range platforms.Items { - p := p // pin - if p.Name != thisPlatform.Name && platformutil.IsActive(&p) { - return true, nil - } - } - - return false, nil -} diff --git a/pkg/controller/integrationprofile/action.go b/pkg/controller/integrationprofile/action.go new file mode 100644 index 0000000000..5bd4709640 --- /dev/null +++ b/pkg/controller/integrationprofile/action.go @@ -0,0 +1,54 @@ +/* +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 integrationprofile + +import ( + "context" + + 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/log" +) + +// Action --. +type Action interface { + client.Injectable + log.Injectable + + // a user friendly name for the action + Name() string + + // returns true if the action can handle the integration profile + CanHandle(profile *v1.IntegrationProfile) bool + + // executes the handling function + Handle(ctx context.Context, profile *v1.IntegrationProfile) (*v1.IntegrationProfile, error) +} + +type baseAction struct { + client client.Client + L log.Logger +} + +func (action *baseAction) InjectClient(client client.Client) { + action.client = client +} + +func (action *baseAction) InjectLogger(log log.Logger) { + action.L = log +} diff --git a/pkg/controller/integrationprofile/initialize.go b/pkg/controller/integrationprofile/initialize.go new file mode 100644 index 0000000000..85f704310d --- /dev/null +++ b/pkg/controller/integrationprofile/initialize.go @@ -0,0 +1,58 @@ +/* +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 integrationprofile + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" +) + +// NewInitializeAction returns the action that initializes the integration profile when not provided by the user. +func NewInitializeAction() Action { + return &initializeAction{} +} + +type initializeAction struct { + baseAction +} + +func (action *initializeAction) Name() string { + return "initialize" +} + +func (action *initializeAction) CanHandle(profile *v1.IntegrationProfile) bool { + return profile.Status.Phase == v1.IntegrationProfilePhaseNone +} + +func (action *initializeAction) Handle(ctx context.Context, profile *v1.IntegrationProfile) (*v1.IntegrationProfile, error) { + action.L.Info("Initializing IntegrationProfile") + profile.ResyncStatusFullConfig() + + profile.Status.SetCondition( + v1.IntegrationProfileConditionTypeCreated, + corev1.ConditionTrue, + v1.IntegrationProfileConditionCreatedReason, + "integration profile created") + + profile.Status.Phase = v1.IntegrationProfilePhaseReady + + return profile, nil +} diff --git a/pkg/controller/integrationprofile/integrationprofile_controller.go b/pkg/controller/integrationprofile/integrationprofile_controller.go new file mode 100644 index 0000000000..7cee700076 --- /dev/null +++ b/pkg/controller/integrationprofile/integrationprofile_controller.go @@ -0,0 +1,216 @@ +/* +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 integrationprofile + +import ( + "context" + "time" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/tools/record" + + ctrl "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/client" + camelevent "github.com/apache/camel-k/v2/pkg/event" + "github.com/apache/camel-k/v2/pkg/platform" + "github.com/apache/camel-k/v2/pkg/util/monitoring" +) + +// Add creates a new IntegrationProfile 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 { + return add(mgr, newReconciler(mgr, c)) +} + +func newReconciler(mgr manager.Manager, c client.Client) reconcile.Reconciler { + return monitoring.NewInstrumentedReconciler( + &reconcileIntegrationProfile{ + client: c, + reader: mgr.GetAPIReader(), + scheme: mgr.GetScheme(), + recorder: mgr.GetEventRecorderFor("camel-k-integration-profile-controller"), + }, + schema.GroupVersionKind{ + Group: v1.SchemeGroupVersion.Group, + Version: v1.SchemeGroupVersion.Version, + Kind: v1.IntegrationProfileKind, + }, + ) +} + +func add(mgr manager.Manager, r reconcile.Reconciler) error { + c, err := controller.New("integrationprofile-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to primary resource IntegrationProfile + err = c.Watch(source.Kind(mgr.GetCache(), &v1.IntegrationProfile{}), + &handler.EnqueueRequestForObject{}, + platform.FilteringFuncs{ + UpdateFunc: func(e event.UpdateEvent) bool { + oldIntegrationProfile, ok := e.ObjectOld.(*v1.IntegrationProfile) + if !ok { + return false + } + newIntegrationProfile, ok := e.ObjectNew.(*v1.IntegrationProfile) + if !ok { + return false + } + // Ignore updates to the integration profile status in which case metadata.Generation + // does not change, or except when the integration profile phase changes as it's used + // to transition from one phase to another + return oldIntegrationProfile.Generation != newIntegrationProfile.Generation || + oldIntegrationProfile.Status.Phase != newIntegrationProfile.Status.Phase + }, + DeleteFunc: func(e event.DeleteEvent) bool { + // Evaluates to false if the object has been confirmed deleted + return !e.DeleteStateUnknown + }, + }, + ) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &reconcileIntegrationProfile{} + +// reconcileIntegrationProfile reconciles a IntegrationProfile object. +type reconcileIntegrationProfile struct { + // This client, initialized using mgr.Client() above, is a split client + // that reads objects from the cache and writes to the API server + client client.Client + // Non-caching client + reader ctrl.Reader + scheme *runtime.Scheme + recorder record.EventRecorder +} + +// Reconcile reads that state of the cluster for a IntegrationProfile object and makes changes based +// on the state read and what is in the IntegrationProfile.Spec +// Note: +// The Controller will requeue the Request to be processed again if the returned error is non-nil or +// Result.Requeue is true, otherwise upon completion it will remove the work from the queue. +func (r *reconcileIntegrationProfile) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) { + rlog := Log.WithValues("request-namespace", request.Namespace, "request-name", request.Name) + rlog.Debug("Reconciling IntegrationProfile") + + // Make sure the operator is allowed to act on namespace + if ok, err := platform.IsOperatorAllowedOnNamespace(ctx, r.client, request.Namespace); err != nil { + return reconcile.Result{}, err + } else if !ok { + rlog.Info("Ignoring request because namespace is locked") + return reconcile.Result{}, nil + } + + // Fetch the IntegrationProfile instance + var instance v1.IntegrationProfile + + if err := r.client.Get(ctx, request.NamespacedName, &instance); err != nil { + if k8serrors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile request. + // Owned objects are automatically garbage collected. For additional cleanup + // logic use finalizers. + + // Return and don't requeue + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + // Only process resources assigned to the operator + if !platform.IsOperatorHandlerConsideringLock(ctx, r.client, request.Namespace, &instance) { + rlog.Info("Ignoring request because resource is not assigned to current operator") + return reconcile.Result{}, nil + } + + actions := []Action{ + NewInitializeAction(), + NewMonitorAction(), + } + + var targetPhase v1.IntegrationProfilePhase + var err error + + target := instance.DeepCopy() + targetLog := rlog.ForIntegrationProfile(target) + + for _, a := range actions { + a.InjectClient(r.client) + a.InjectLogger(targetLog) + + if a.CanHandle(target) { + targetLog.Infof("Invoking action %s", a.Name()) + + phaseFrom := target.Status.Phase + + target, err = a.Handle(ctx, target) + if err != nil { + camelevent.NotifyIntegrationProfileError(ctx, r.client, r.recorder, &instance, target, err) + return reconcile.Result{}, err + } + + if target != nil { + target.Status.ObservedGeneration = instance.Generation + + if err := r.client.Status().Patch(ctx, target, ctrl.MergeFrom(&instance)); err != nil { + camelevent.NotifyIntegrationProfileError(ctx, r.client, r.recorder, &instance, target, err) + return reconcile.Result{}, err + } + + targetPhase = target.Status.Phase + + if targetPhase != phaseFrom { + targetLog.Info( + "State transition", + "phase-from", phaseFrom, + "phase-to", target.Status.Phase, + ) + } + } + + // handle one action at time so the resource + // is always at its latest state + camelevent.NotifyIntegrationProfileUpdated(ctx, r.client, r.recorder, &instance, target) + break + } + } + + if targetPhase == v1.IntegrationProfilePhaseReady { + return reconcile.Result{}, nil + } + + // Requeue + return reconcile.Result{ + RequeueAfter: 5 * time.Second, + }, nil +} diff --git a/pkg/controller/integrationprofile/log.go b/pkg/controller/integrationprofile/log.go new file mode 100644 index 0000000000..c377ad9067 --- /dev/null +++ b/pkg/controller/integrationprofile/log.go @@ -0,0 +1,23 @@ +/* +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 integrationprofile + +import "github.com/apache/camel-k/v2/pkg/util/log" + +// Log --. +var Log = log.Log.WithName("controller").WithName("integrationprofile") diff --git a/pkg/controller/integrationprofile/monitor.go b/pkg/controller/integrationprofile/monitor.go new file mode 100644 index 0000000000..f980c9ffb0 --- /dev/null +++ b/pkg/controller/integrationprofile/monitor.go @@ -0,0 +1,47 @@ +/* +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 integrationprofile + +import ( + "context" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" +) + +// NewMonitorAction returns an action that monitors the integration profile after it's fully initialized. +func NewMonitorAction() Action { + return &monitorAction{} +} + +type monitorAction struct { + baseAction +} + +func (action *monitorAction) Name() string { + return "monitor" +} + +func (action *monitorAction) CanHandle(profile *v1.IntegrationProfile) bool { + return profile.Status.Phase == v1.IntegrationProfilePhaseReady +} + +func (action *monitorAction) Handle(ctx context.Context, profile *v1.IntegrationProfile) (*v1.IntegrationProfile, error) { + // Refresh applied profile + profile.ResyncStatusFullConfig() + return profile, nil +} diff --git a/pkg/controller/kameletbinding/monitor.go b/pkg/controller/kameletbinding/monitor.go index 2c23d062ae..2c6d409f89 100644 --- a/pkg/controller/kameletbinding/monitor.go +++ b/pkg/controller/kameletbinding/monitor.go @@ -76,6 +76,12 @@ func (action *monitorAction) Handle(ctx context.Context, binding *v1alpha1.Kamel operatorIDChanged := v1.GetOperatorIDAnnotation(binding) != "" && (v1.GetOperatorIDAnnotation(binding) != v1.GetOperatorIDAnnotation(&it)) + integrationProfileChanged := v1.GetIntegrationProfileAnnotation(binding) != "" && + (v1.GetIntegrationProfileAnnotation(binding) != v1.GetIntegrationProfileAnnotation(&it)) + + integrationProfileNamespaceChanged := v1.GetIntegrationProfileNamespaceAnnotation(binding) != "" && + (v1.GetIntegrationProfileNamespaceAnnotation(binding) != v1.GetIntegrationProfileNamespaceAnnotation(&it)) + sameTraits, err := trait.IntegrationAndKameletBindingSameTraits(&it, binding) if err != nil { return nil, err @@ -92,11 +98,12 @@ func (action *monitorAction) Handle(ctx context.Context, binding *v1alpha1.Kamel semanticEquality := equality.Semantic.DeepDerivative(expected.Spec, it.Spec) - if !semanticEquality || operatorIDChanged || !sameTraits { + if !semanticEquality || operatorIDChanged || integrationProfileChanged || integrationProfileNamespaceChanged || !sameTraits { action.L.Info( "Binding needs a rebuild", "semantic-equality", !semanticEquality, "operatorid-changed", operatorIDChanged, + "integration-profile-changed", integrationProfileChanged || integrationProfileNamespaceChanged, "traits-changed", !sameTraits) // Binding has changed and needs rebuild diff --git a/pkg/controller/pipe/monitor.go b/pkg/controller/pipe/monitor.go index 292add27aa..44684db1b4 100644 --- a/pkg/controller/pipe/monitor.go +++ b/pkg/controller/pipe/monitor.go @@ -51,14 +51,14 @@ func (action *monitorAction) CanHandle(binding *v1.Pipe) bool { binding.Status.Phase == v1.PipePhaseReady } -func (action *monitorAction) Handle(ctx context.Context, binding *v1.Pipe) (*v1.Pipe, error) { +func (action *monitorAction) Handle(ctx context.Context, pipe *v1.Pipe) (*v1.Pipe, error) { key := client.ObjectKey{ - Namespace: binding.Namespace, - Name: binding.Name, + Namespace: pipe.Namespace, + Name: pipe.Name, } it := v1.Integration{} if err := action.client.Get(ctx, key, &it); err != nil && k8serrors.IsNotFound(err) { - target := binding.DeepCopy() + target := pipe.DeepCopy() // Rebuild the integration target.Status.Phase = v1.PipePhaseNone target.Status.SetCondition( @@ -69,22 +69,28 @@ func (action *monitorAction) Handle(ctx context.Context, binding *v1.Pipe) (*v1. ) return target, nil } else if err != nil { - return nil, fmt.Errorf("could not load integration for Pipe %q: %w", binding.Name, err) + return nil, fmt.Errorf("could not load integration for Pipe %q: %w", pipe.Name, err) } - operatorIDChanged := v1.GetOperatorIDAnnotation(binding) != "" && - (v1.GetOperatorIDAnnotation(binding) != v1.GetOperatorIDAnnotation(&it)) + operatorIDChanged := v1.GetOperatorIDAnnotation(pipe) != "" && + (v1.GetOperatorIDAnnotation(pipe) != v1.GetOperatorIDAnnotation(&it)) - sameTraits, err := trait.IntegrationAndPipeSameTraits(&it, binding) + integrationProfileChanged := v1.GetIntegrationProfileAnnotation(pipe) != "" && + (v1.GetIntegrationProfileAnnotation(pipe) != v1.GetIntegrationProfileAnnotation(&it)) + + integrationProfileNamespaceChanged := v1.GetIntegrationProfileNamespaceAnnotation(pipe) != "" && + (v1.GetIntegrationProfileNamespaceAnnotation(pipe) != v1.GetIntegrationProfileNamespaceAnnotation(&it)) + + sameTraits, err := trait.IntegrationAndPipeSameTraits(&it, pipe) if err != nil { return nil, err } // Check if the integration needs to be changed - expected, err := CreateIntegrationFor(ctx, action.client, binding) - if binding.Spec.Integration != nil { - action.L.Infof("Pipe %s is using deprecated .spec.integration parameter. Please, update and use annotation traits instead", binding.Name) - binding.Status.SetCondition( + expected, err := CreateIntegrationFor(ctx, action.client, pipe) + if pipe.Spec.Integration != nil { + action.L.Infof("Pipe %s is using deprecated .spec.integration parameter. Please, update and use annotation traits instead", pipe.Name) + pipe.Status.SetCondition( v1.PipeIntegrationDeprecationNotice, corev1.ConditionTrue, ".spec.integration parameter is deprecated", @@ -92,23 +98,24 @@ func (action *monitorAction) Handle(ctx context.Context, binding *v1.Pipe) (*v1. ) } if err != nil { - binding.Status.Phase = v1.PipePhaseError - binding.Status.SetErrorCondition(v1.PipeIntegrationConditionError, + pipe.Status.Phase = v1.PipePhaseError + pipe.Status.SetErrorCondition(v1.PipeIntegrationConditionError, "Couldn't create an Integration custom resource", err) - return binding, err + return pipe, err } semanticEquality := equality.Semantic.DeepDerivative(expected.Spec, it.Spec) - if !semanticEquality || operatorIDChanged || !sameTraits { + if !semanticEquality || operatorIDChanged || integrationProfileChanged || integrationProfileNamespaceChanged || !sameTraits { action.L.Info( "Pipe needs a rebuild", "semantic-equality", !semanticEquality, "operatorid-changed", operatorIDChanged, + "integration-profile-changed", integrationProfileChanged || integrationProfileNamespaceChanged, "traits-changed", !sameTraits) // Pipe has changed and needs rebuild - target := binding.DeepCopy() + target := pipe.DeepCopy() // Rebuild the integration target.Status.Phase = v1.PipePhaseNone target.Status.SetCondition( @@ -121,7 +128,7 @@ func (action *monitorAction) Handle(ctx context.Context, binding *v1.Pipe) (*v1. } // Map integration phase and conditions to Pipe - target := binding.DeepCopy() + target := pipe.DeepCopy() switch it.Status.Phase { diff --git a/pkg/event/manager.go b/pkg/event/manager.go index 106287b73a..2c629990f4 100644 --- a/pkg/event/manager.go +++ b/pkg/event/manager.go @@ -56,6 +56,13 @@ const ( // ReasonIntegrationPlatformError --. ReasonIntegrationPlatformError = "IntegrationPlatformError" + // ReasonIntegrationProfilePhaseUpdated --. + ReasonIntegrationProfilePhaseUpdated = "IntegrationProfilePhaseUpdated" + // ReasonIntegrationProfileConditionChanged --. + ReasonIntegrationProfileConditionChanged = "IntegrationProfileConditionChanged" + // ReasonIntegrationProfileError --. + ReasonIntegrationProfileError = "IntegrationProfileError" + // ReasonBuildPhaseUpdated --. ReasonBuildPhaseUpdated = "BuildPhaseUpdated" // ReasonBuildConditionChanged --. @@ -168,6 +175,35 @@ func NotifyIntegrationPlatformError(ctx context.Context, c client.Client, record recorder.Eventf(p, corev1.EventTypeWarning, ReasonIntegrationPlatformError, "Cannot reconcile Integration Platform %s: %v", p.Name, err) } +// NotifyIntegrationProfileUpdated automatically generates events when a integration profile changes. +func NotifyIntegrationProfileUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, old, newResource *v1.IntegrationProfile) { + if newResource == nil { + return + } + oldPhase := "" + var oldConditions []v1.ResourceCondition + if old != nil { + oldPhase = string(old.Status.Phase) + oldConditions = old.Status.GetConditions() + } + if newResource.Status.Phase != v1.IntegrationProfilePhaseNone { + notifyIfConditionUpdated(recorder, newResource, oldConditions, newResource.Status.GetConditions(), "Integration Profile", newResource.Name, ReasonIntegrationProfileConditionChanged) + } + notifyIfPhaseUpdated(ctx, c, recorder, newResource, oldPhase, string(newResource.Status.Phase), "Integration Profile", newResource.Name, ReasonIntegrationProfilePhaseUpdated, "") +} + +// NotifyIntegrationProfileError automatically generates error events when the integration Platform reconcile cycle phase has an error. +func NotifyIntegrationProfileError(ctx context.Context, c client.Client, recorder record.EventRecorder, old, newResource *v1.IntegrationProfile, err error) { + p := old + if newResource != nil { + p = newResource + } + if p == nil { + return + } + recorder.Eventf(p, corev1.EventTypeWarning, ReasonIntegrationProfileError, "Cannot reconcile Integration Profile %s: %v", p.Name, err) +} + // NotifyCamelCatalogUpdated automatically generates events when a CamelCatalog changes. func NotifyCamelCatalogUpdated(ctx context.Context, c client.Client, recorder record.EventRecorder, old, newResource *v1.CamelCatalog) { if newResource == nil { diff --git a/pkg/install/cluster.go b/pkg/install/cluster.go index 2b0e85a6d3..ba54fe737d 100644 --- a/pkg/install/cluster.go +++ b/pkg/install/cluster.go @@ -170,6 +170,12 @@ func installCRDs(ctx context.Context, c client.Client, collection *kubernetes.Co return err } + // Install CRD for Integration Profile (if needed) + if err := installCRD(ctx, c, "IntegrationProfile", "v1", "camel.apache.org_integrationprofiles.yaml", + v1beta1Customizer, collection, force); err != nil { + return err + } + // Install CRD for Integration Kit (if needed) if err := installCRD(ctx, c, "IntegrationKit", "v1", "camel.apache.org_integrationkits.yaml", v1beta1Customizer, collection, force); err != nil { @@ -295,6 +301,11 @@ func areAllCrdInstalled(c client.Client) (int, error) { } else if !ok { return 1, nil } + if ok, err := isCrdInstalled(c, "IntegrationProfile", "v1"); err != nil { + return 1, fmt.Errorf("error installing IntegrationProfile CRDs: %w", err) + } else if !ok { + return 1, nil + } if ok, err := isCrdInstalled(c, "IntegrationKit", "v1"); err != nil { return 2, fmt.Errorf("error installing IntegrationKit CRDs: %w", err) } else if !ok { diff --git a/pkg/install/platform.go b/pkg/install/platform.go index 4942315645..ffc54ad372 100644 --- a/pkg/install/platform.go +++ b/pkg/install/platform.go @@ -23,7 +23,7 @@ import ( "github.com/apache/camel-k/v2/pkg/client" ) -// IntegrationPlatformViewerRole installs the role that allows any user to access integrationplatforms in the global namespace. +// IntegrationPlatformViewerRole installs the role that allows any user to access integrationplatforms and integrationprofiles in the global namespace. func IntegrationPlatformViewerRole(ctx context.Context, c client.Client, namespace string) error { if err := Resource(ctx, c, namespace, true, IdentityResourceCustomizer, "/resources/viewer/user-global-platform-viewer-role.yaml"); err != nil { return err diff --git a/pkg/platform/defaults.go b/pkg/platform/defaults.go index 61b5278295..0f97c46769 100644 --- a/pkg/platform/defaults.go +++ b/pkg/platform/defaults.go @@ -190,22 +190,15 @@ func configureRegistry(ctx context.Context, c client.Client, p *v1.IntegrationPl func applyGlobalPlatformDefaults(ctx context.Context, c client.Client, p *v1.IntegrationPlatform) error { operatorNamespace := GetOperatorNamespace() - if operatorNamespace != "" && operatorNamespace != p.Namespace { + if operatorNamespace != "" { operatorID := defaults.OperatorID() - if operatorID != "" { - if globalPlatform, err := get(ctx, c, operatorNamespace, operatorID); err != nil && !k8serrors.IsNotFound(err) { + if operatorNamespace != p.Namespace || (operatorID != "" && p.Name != operatorID) { + if globalPlatform, err := findLocal(ctx, c, operatorNamespace); err != nil && !k8serrors.IsNotFound(err) { return err } else if globalPlatform != nil { applyPlatformSpec(globalPlatform, p) - return nil } } - - if globalPlatform, err := findLocal(ctx, c, operatorNamespace, true); err != nil && !k8serrors.IsNotFound(err) { - return err - } else if globalPlatform != nil { - applyPlatformSpec(globalPlatform, p) - } } return nil diff --git a/pkg/platform/operator.go b/pkg/platform/operator.go index 16f6cb0dd4..e9bebd0093 100644 --- a/pkg/platform/operator.go +++ b/pkg/platform/operator.go @@ -113,7 +113,7 @@ func IsNamespaceLocked(ctx context.Context, c ctrl.Reader, namespace string) (bo return false, nil } - platforms, err := ListPrimaryPlatforms(ctx, c, namespace) + platforms, err := ListPlatforms(ctx, c, namespace) if err != nil { return true, err } @@ -265,10 +265,21 @@ func (f FilteringFuncs) Update(e event.UpdateEvent) bool { if !IsOperatorHandler(e.ObjectNew) { return false } - if e.ObjectOld != nil && e.ObjectNew != nil && - camelv1.GetOperatorIDAnnotation(e.ObjectOld) != camelv1.GetOperatorIDAnnotation(e.ObjectNew) { - // Always force reconciliation when the object becomes managed by the current operator - return true + if e.ObjectOld != nil && e.ObjectNew != nil { + if camelv1.GetOperatorIDAnnotation(e.ObjectOld) != camelv1.GetOperatorIDAnnotation(e.ObjectNew) { + // Always force reconciliation when the object becomes managed by the current operator + return true + } + + if camelv1.GetIntegrationProfileAnnotation(e.ObjectOld) != camelv1.GetIntegrationProfileAnnotation(e.ObjectNew) { + // Always force reconciliation when the object gets attached to a new integration profile + return true + } + + if camelv1.GetIntegrationProfileNamespaceAnnotation(e.ObjectOld) != camelv1.GetIntegrationProfileNamespaceAnnotation(e.ObjectNew) { + // Always force reconciliation when the object gets attached to a new integration profile + return true + } } if f.UpdateFunc != nil { return f.UpdateFunc(e) diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go index 2a93f52273..9963f855e2 100644 --- a/pkg/platform/platform.go +++ b/pkg/platform/platform.go @@ -21,6 +21,7 @@ import ( "context" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "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" k8serrors "k8s.io/apimachinery/pkg/api/errors" @@ -54,57 +55,58 @@ func LookupForPlatformName(ctx context.Context, c k8sclient.Reader, name string) } func GetForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object) (*v1.IntegrationPlatform, error) { - return GetOrFindForResource(ctx, c, o, true) -} - -func GetOrFindForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object, active bool) (*v1.IntegrationPlatform, error) { - return getOrFindForResource(ctx, c, o, active, false) -} - -func GetOrFindLocalForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object, active bool) (*v1.IntegrationPlatform, error) { - return getOrFindForResource(ctx, c, o, active, true) -} + var ip *v1.IntegrationPlatform + var err error -func GetOrFindLocal(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) { - return findLocal(ctx, c, namespace, true) -} - -func getOrFindForResource(ctx context.Context, c k8sclient.Reader, o k8sclient.Object, active bool, local bool) (*v1.IntegrationPlatform, error) { if selectedPlatform, ok := o.GetAnnotations()[v1.PlatformSelectorAnnotation]; ok { - return get(ctx, c, o.GetNamespace(), selectedPlatform) + ip, err = getOrFindAny(ctx, c, o.GetNamespace(), selectedPlatform) + if err != nil { + return nil, err + } } - if it, ok := o.(*v1.Integration); ok { - return getOrFind(ctx, c, it.Namespace, it.Status.Platform, active, local) - } else if ik, ok := o.(*v1.IntegrationKit); ok { - return getOrFind(ctx, c, ik.Namespace, ik.Status.Platform, active, local) + if ip == nil { + if it, ok := o.(*v1.Integration); ok { + ip, err = getOrFindAny(ctx, c, it.Namespace, it.Status.Platform) + if err != nil { + return nil, err + } + } else if ik, ok := o.(*v1.IntegrationKit); ok { + ip, err = getOrFindAny(ctx, c, ik.Namespace, ik.Status.Platform) + if err != nil { + return nil, err + } + } } - return find(ctx, c, o.GetNamespace(), active, local) -} -func getOrFind(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool, local bool) (*v1.IntegrationPlatform, error) { - if local { - return getOrFindLocal(ctx, c, namespace, name, active) + if ip == nil { + ip, err = findAny(ctx, c, o.GetNamespace()) + if err != nil { + return nil, err + } } - return getOrFindAny(ctx, c, namespace, name, active) + + return ip, nil } -// getOrFindAny returns the named platform or any other platform in the local namespace or the global one. -func getOrFindAny(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) { - if name != "" { - return get(ctx, c, namespace, name) - } +func GetForName(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1.IntegrationPlatform, error) { + return getOrFindAny(ctx, c, namespace, name) +} - return findAny(ctx, c, namespace, active) +func GetOrFindLocal(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) { + return findLocal(ctx, c, namespace) } -// getOrFindLocal returns the named platform or any other platform in the local namespace. -func getOrFindLocal(ctx context.Context, c k8sclient.Reader, namespace string, name string, active bool) (*v1.IntegrationPlatform, error) { +// getOrFindAny returns the named platform or any other platform in the local namespace or the global one. +func getOrFindAny(ctx context.Context, c k8sclient.Reader, namespace string, name string) (*v1.IntegrationPlatform, error) { if name != "" { - return get(ctx, c, namespace, name) + pl, err := get(ctx, c, namespace, name) + if pl != nil { + return pl, err + } } - return findLocal(ctx, c, namespace, active) + return findAny(ctx, c, namespace) } // get returns the given platform in the given namespace or the global one. @@ -119,72 +121,59 @@ func get(ctx context.Context, c k8sclient.Reader, namespace string, name string) return p, err } -func find(ctx context.Context, c k8sclient.Reader, namespace string, active bool, local bool) (*v1.IntegrationPlatform, error) { - if local { - return findLocal(ctx, c, namespace, active) - } - return findAny(ctx, c, namespace, active) -} - // findAny returns the currently installed platform or any platform existing in local or operator namespace. -func findAny(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) { - p, err := findLocal(ctx, c, namespace, active) +func findAny(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) { + p, err := findLocal(ctx, c, namespace) if err != nil && k8serrors.IsNotFound(err) { operatorNamespace := GetOperatorNamespace() if operatorNamespace != "" && operatorNamespace != namespace { - p, err = findLocal(ctx, c, operatorNamespace, active) + p, err = findLocal(ctx, c, operatorNamespace) } } return p, err } // findLocal returns the currently installed platform or any platform existing in local namespace. -func findLocal(ctx context.Context, c k8sclient.Reader, namespace string, active bool) (*v1.IntegrationPlatform, error) { +func findLocal(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatform, error) { log.Debug("Finding available platforms") - lst, err := ListPrimaryPlatforms(ctx, c, namespace) + operatorNamespace := GetOperatorNamespace() + if namespace == operatorNamespace { + operatorID := defaults.OperatorID() + if operatorID != "" { + if p, err := get(ctx, c, operatorNamespace, operatorID); err == nil { + return p, nil + } + } + } + + lst, err := ListPlatforms(ctx, c, namespace) if err != nil { return nil, err } + var fallback *v1.IntegrationPlatform for _, platform := range lst.Items { platform := platform // pin if IsActive(&platform) { - log.Debugf("Found active local integration platform %s", platform.Name) + log.Debugf("Found active integration platform %s", platform.Name) return &platform, nil + } else { + fallback = &platform } } - if !active && len(lst.Items) > 0 { - // does not require the platform to be active, just return one if present - res := lst.Items[0] - log.Debugf("Found local integration platform %s", res.Name) - return &res, nil + if fallback != nil { + log.Debugf("Found inactive integration platform %s", fallback.Name) + return fallback, nil } - log.Debugf("Not found a local integration platform") + log.Debugf("Unable to find integration platform") return nil, k8serrors.NewNotFound(v1.Resource("IntegrationPlatform"), DefaultPlatformName) } -// ListPrimaryPlatforms returns all non-secondary platforms installed in a given namespace (only one will be active). -func ListPrimaryPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) { - lst, err := ListAllPlatforms(ctx, c, namespace) - if err != nil { - return nil, err - } - - filtered := v1.NewIntegrationPlatformList() - for i := range lst.Items { - pl := lst.Items[i] - if !IsSecondary(&pl) { - filtered.Items = append(filtered.Items, pl) - } - } - return &filtered, nil -} - -// ListAllPlatforms returns all platforms installed in a given namespace. -func ListAllPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) { +// ListPlatforms returns all platforms installed in a given namespace. +func ListPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) { lst := v1.NewIntegrationPlatformList() if err := c.List(ctx, &lst, k8sclient.InNamespace(namespace)); err != nil { return nil, err @@ -194,15 +183,7 @@ func ListAllPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) // IsActive determines if the given platform is being used. func IsActive(p *v1.IntegrationPlatform) bool { - return p.Status.Phase != "" && p.Status.Phase != v1.IntegrationPlatformPhaseDuplicate -} - -// IsSecondary determines if the given platform is marked as secondary. -func IsSecondary(p *v1.IntegrationPlatform) bool { - if l, ok := p.Annotations[v1.SecondaryPlatformAnnotation]; ok && l == "true" { - return true - } - return false + return p.Status.Phase != v1.IntegrationPlatformPhaseNone } // GetTraitProfile returns the current profile of the platform (if present) or returns the default one for the cluster. diff --git a/pkg/platform/profile.go b/pkg/platform/profile.go new file mode 100644 index 0000000000..8f9459a958 --- /dev/null +++ b/pkg/platform/profile.go @@ -0,0 +1,138 @@ +/* +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 platform + +import ( + "context" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/util" + "github.com/apache/camel-k/v2/pkg/util/kubernetes" + "github.com/apache/camel-k/v2/pkg/util/log" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// ApplyIntegrationProfile resolves integration profile from given object and applies the profile settings to the given integration platform. +func ApplyIntegrationProfile(ctx context.Context, c k8sclient.Reader, ip *v1.IntegrationPlatform, o k8sclient.Object) (*v1.IntegrationProfile, error) { + profile, err := findIntegrationProfile(ctx, c, o) + if err != nil && !k8serrors.IsNotFound(err) { + return nil, err + } + + if ip == nil || profile == nil { + return nil, nil + } + + if profile.Status.Build.RuntimeVersion != "" && profile.Status.Build.RuntimeVersion != ip.Status.Build.RuntimeVersion { + log.Debugf("Integration Platform %s [%s]: setting runtime version", ip.Name, ip.Namespace) + ip.Status.Build.RuntimeVersion = profile.Status.Build.RuntimeVersion + } + + if profile.Status.Build.RuntimeProvider != "" && profile.Status.Build.RuntimeProvider != ip.Status.Build.RuntimeProvider { + log.Debugf("Integration Platform %s [%s]: setting runtime provider", ip.Name, ip.Namespace) + ip.Status.Build.RuntimeProvider = profile.Status.Build.RuntimeProvider + } + + if profile.Status.Build.BaseImage != "" && profile.Status.Build.BaseImage != ip.Status.Build.BaseImage { + log.Debugf("Integration Platform %s [%s]: setting base image", ip.Name, ip.Namespace) + ip.Status.Build.BaseImage = profile.Status.Build.BaseImage + } + + if profile.Status.Build.Maven.LocalRepository != "" && + profile.Status.Build.Maven.LocalRepository != ip.Status.Build.Maven.LocalRepository { + log.Debugf("Integration Platform %s [%s]: setting local repository", ip.Name, ip.Namespace) + ip.Status.Build.Maven.LocalRepository = profile.Status.Build.Maven.LocalRepository + } + + if len(profile.Status.Build.Maven.CLIOptions) > 0 { + log.Debugf("Integration Platform %s [%s]: setting CLI options", ip.Name, ip.Namespace) + if len(ip.Status.Build.Maven.CLIOptions) == 0 { + ip.Status.Build.Maven.CLIOptions = make([]string, len(profile.Status.Build.Maven.CLIOptions)) + copy(ip.Status.Build.Maven.CLIOptions, profile.Status.Build.Maven.CLIOptions) + } else { + util.StringSliceUniqueConcat(&ip.Status.Build.Maven.CLIOptions, profile.Status.Build.Maven.CLIOptions) + } + } + + if len(profile.Status.Build.Maven.Properties) > 0 { + log.Debugf("Integration Platform %s [%s]: setting Maven properties", ip.Name, ip.Namespace) + if len(ip.Status.Build.Maven.Properties) == 0 { + ip.Status.Build.Maven.Properties = make(map[string]string, len(profile.Status.Build.Maven.Properties)) + } + + for key, val := range profile.Status.Build.Maven.Properties { + // only set unknown properties on target + if _, ok := ip.Status.Build.Maven.Properties[key]; !ok { + ip.Status.Build.Maven.Properties[key] = val + } + } + } + + if len(profile.Status.Build.Maven.Extension) > 0 && len(ip.Status.Build.Maven.Extension) == 0 { + log.Debugf("Integration Platform %s [%s]: setting Maven extensions", ip.Name, ip.Namespace) + ip.Status.Build.Maven.Extension = make([]v1.MavenArtifact, len(profile.Status.Build.Maven.Extension)) + copy(ip.Status.Build.Maven.Extension, profile.Status.Build.Maven.Extension) + } + + if profile.Status.Build.Registry.Address != "" && profile.Status.Build.Registry.Address != ip.Status.Build.Registry.Address { + log.Debugf("Integration Platform %s [%s]: setting registry", ip.Name, ip.Namespace) + profile.Status.Build.Registry.DeepCopyInto(&ip.Status.Build.Registry) + } + + if err := ip.Status.Traits.Merge(profile.Status.Traits); err != nil { + log.Errorf(err, "Integration Platform %s [%s]: failed to merge traits", ip.Name, ip.Namespace) + } else if err := ip.Status.Traits.Merge(ip.Spec.Traits); err != nil { + log.Errorf(err, "Integration Platform %s [%s]: failed to merge traits", ip.Name, ip.Namespace) + } + + // Build timeout + if profile.Status.Build.Timeout != nil { + log.Debugf("Integration Platform %s [%s]: setting build timeout", ip.Name, ip.Namespace) + ip.Status.Build.Timeout = profile.Status.Build.Timeout + } + + if len(profile.Status.Kamelet.Repositories) > 0 { + log.Debugf("Integration Platform %s [%s]: setting kamelet repositories", ip.Name, ip.Namespace) + ip.Status.Kamelet.Repositories = append(ip.Status.Kamelet.Repositories, profile.Status.Kamelet.Repositories...) + } + + return profile, nil +} + +// findIntegrationProfile finds profile from given resource annotations and resolves the profile in given resource namespace or operator namespace as a fallback option. +func findIntegrationProfile(ctx context.Context, c k8sclient.Reader, o k8sclient.Object) (*v1.IntegrationProfile, error) { + if profileName := v1.GetIntegrationProfileAnnotation(o); profileName != "" { + namespace := v1.GetIntegrationProfileNamespaceAnnotation(o) + if namespace == "" { + namespace = o.GetNamespace() + } + + profile, err := kubernetes.GetIntegrationProfile(ctx, c, profileName, namespace) + if err != nil && k8serrors.IsNotFound(err) { + operatorNamespace := GetOperatorNamespace() + if operatorNamespace != "" && operatorNamespace != namespace { + profile, err = kubernetes.GetIntegrationProfile(ctx, c, profileName, operatorNamespace) + } + } + return profile, err + } + + return nil, nil +} diff --git a/pkg/platform/profile_test.go b/pkg/platform/profile_test.go new file mode 100644 index 0000000000..6d14e8e336 --- /dev/null +++ b/pkg/platform/profile_test.go @@ -0,0 +1,322 @@ +/* +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 platform + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" + "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" + "github.com/apache/camel-k/v2/pkg/util/test" +) + +func TestFindIntegrationProfile(t *testing.T) { + profile := v1.IntegrationProfile{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom", + Namespace: "ns", + }, + } + + profile.ResyncStatusFullConfig() + + c, err := test.NewFakeClient(&profile) + assert.Nil(t, err) + + integration := v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "ns", + Annotations: map[string]string{ + v1.IntegrationProfileAnnotation: "custom", + }, + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseRunning, + }, + } + + found, err := findIntegrationProfile(context.TODO(), c, &integration) + assert.Nil(t, err) + assert.NotNil(t, found) +} + +func TestFindIntegrationProfileWithNamespace(t *testing.T) { + profile := v1.IntegrationProfile{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom", + Namespace: "other", + }, + } + + profile.ResyncStatusFullConfig() + + c, err := test.NewFakeClient(&profile) + assert.Nil(t, err) + + integration := v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "ns", + Annotations: map[string]string{ + v1.IntegrationProfileAnnotation: "custom", + v1.IntegrationProfileNamespaceAnnotation: "other", + }, + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseRunning, + }, + } + + found, err := findIntegrationProfile(context.TODO(), c, &integration) + assert.Nil(t, err) + assert.NotNil(t, found) +} + +func TestFindIntegrationProfileInOperatorNamespace(t *testing.T) { + profile := v1.IntegrationProfile{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom", + Namespace: "operator-namespace", + }, + } + + profile.ResyncStatusFullConfig() + + c, err := test.NewFakeClient(&profile) + assert.Nil(t, err) + + t.Setenv(operatorNamespaceEnvVariable, "operator-namespace") + + integration := v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "ns", + Annotations: map[string]string{ + v1.IntegrationProfileAnnotation: "custom", + }, + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseRunning, + }, + } + + found, err := findIntegrationProfile(context.TODO(), c, &integration) + assert.Nil(t, err) + assert.NotNil(t, found) +} + +func TestApplyIntegrationProfile(t *testing.T) { + profile := v1.IntegrationProfile{ + ObjectMeta: metav1.ObjectMeta{ + Name: "custom", + Namespace: "ns", + }, + Spec: v1.IntegrationProfileSpec{ + Build: v1.IntegrationProfileBuildSpec{ + Maven: v1.MavenSpec{ + Properties: map[string]string{ + "global_prop1": "global_value1", + "global_prop2": "global_value2", + }, + CLIOptions: []string{ + "-V", + "--no-transfer-progress", + "-Dstyle.color=never", + "-E", + }, + }, + RuntimeVersion: "0.99.0", + }, + Traits: v1.Traits{ + Logging: &trait.LoggingTrait{ + Level: "DEBUG", + }, + Container: &trait.ContainerTrait{ + ImagePullPolicy: corev1.PullAlways, + LimitCPU: "0.1", + }, + }, + }, + } + + profile.ResyncStatusFullConfig() + + c, err := test.NewFakeClient(&profile) + assert.Nil(t, err) + + ip := v1.IntegrationPlatform{ + ObjectMeta: metav1.ObjectMeta{ + Name: "local-camel-k", + Namespace: "ns", + }, + Spec: v1.IntegrationPlatformSpec{ + Build: v1.IntegrationPlatformBuildSpec{ + BuildConfiguration: v1.BuildConfiguration{ + Strategy: v1.BuildStrategyRoutine, + OrderStrategy: v1.BuildOrderStrategyFIFO, + }, + }, + Cluster: v1.IntegrationPlatformClusterOpenShift, + Profile: v1.TraitProfileOpenShift, + }, + } + + ip.ResyncStatusFullConfig() + + err = ConfigureDefaults(context.TODO(), c, &ip, true) + assert.Nil(t, err) + + integration := v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "ns", + Annotations: map[string]string{ + v1.IntegrationProfileAnnotation: "custom", + }, + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseRunning, + }, + } + + _, err = ApplyIntegrationProfile(context.TODO(), c, &ip, &integration) + assert.NoError(t, err) + + assert.Equal(t, v1.IntegrationPlatformClusterOpenShift, ip.Status.Cluster) + assert.Equal(t, v1.TraitProfileOpenShift, ip.Status.Profile) + assert.Equal(t, v1.BuildStrategyRoutine, ip.Status.Build.BuildConfiguration.Strategy) + assert.Equal(t, v1.BuildOrderStrategyFIFO, ip.Status.Build.BuildConfiguration.OrderStrategy) + assert.True(t, ip.Status.Build.MaxRunningBuilds == 3) // default for build strategy routine + assert.Equal(t, len(profile.Status.Build.Maven.CLIOptions), len(ip.Status.Build.Maven.CLIOptions)) + assert.Equal(t, profile.Status.Build.Maven.CLIOptions, ip.Status.Build.Maven.CLIOptions) + assert.NotNil(t, ip.Status.Traits) + assert.NotNil(t, ip.Status.Traits.Logging) + assert.Equal(t, "DEBUG", ip.Status.Traits.Logging.Level) + assert.NotNil(t, ip.Status.Traits.Container) + assert.Equal(t, corev1.PullAlways, ip.Status.Traits.Container.ImagePullPolicy) + assert.Equal(t, "0.1", ip.Status.Traits.Container.LimitCPU) + assert.Equal(t, 2, len(ip.Status.Build.Maven.Properties)) + assert.Equal(t, "global_value1", ip.Status.Build.Maven.Properties["global_prop1"]) + assert.Equal(t, "global_value2", ip.Status.Build.Maven.Properties["global_prop2"]) +} + +func TestApplyIntegrationProfileAndRetainPlatformSpec(t *testing.T) { + profile := v1.IntegrationProfile{ + ObjectMeta: metav1.ObjectMeta{ + Name: DefaultPlatformName, + Namespace: "ns", + }, + Spec: v1.IntegrationProfileSpec{ + Build: v1.IntegrationProfileBuildSpec{ + Maven: v1.MavenSpec{ + Properties: map[string]string{ + "global_prop1": "global_value1", + "global_prop2": "global_value2", + }, + }, + }, + Traits: v1.Traits{ + Logging: &trait.LoggingTrait{ + Level: "DEBUG", + }, + Container: &trait.ContainerTrait{ + ImagePullPolicy: corev1.PullIfNotPresent, + LimitCPU: "0.1", + }, + }, + }, + } + + profile.ResyncStatusFullConfig() + + c, err := test.NewFakeClient(&profile) + assert.Nil(t, err) + + ip := v1.IntegrationPlatform{ + ObjectMeta: metav1.ObjectMeta{ + Name: "local-camel-k", + Namespace: "ns", + }, + Spec: v1.IntegrationPlatformSpec{ + Build: v1.IntegrationPlatformBuildSpec{ + BuildConfiguration: v1.BuildConfiguration{ + Strategy: v1.BuildStrategyPod, + OrderStrategy: v1.BuildOrderStrategyFIFO, + }, + MaxRunningBuilds: 1, + Maven: v1.MavenSpec{ + Properties: map[string]string{ + "local_prop1": "local_value1", + "global_prop2": "local_value2", + }, + }, + }, + Traits: v1.Traits{ + Container: &trait.ContainerTrait{ + ImagePullPolicy: corev1.PullAlways, + }, + }, + Cluster: v1.IntegrationPlatformClusterKubernetes, + Profile: v1.TraitProfileKnative, + }, + } + + ip.ResyncStatusFullConfig() + + err = ConfigureDefaults(context.TODO(), c, &ip, true) + assert.Nil(t, err) + + integration := v1.Integration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "ns", + Annotations: map[string]string{ + v1.IntegrationProfileAnnotation: DefaultPlatformName, + }, + }, + Status: v1.IntegrationStatus{ + Phase: v1.IntegrationPhaseRunning, + }, + } + + _, err = ApplyIntegrationProfile(context.TODO(), c, &ip, &integration) + assert.NoError(t, err) + + assert.Equal(t, v1.IntegrationPlatformClusterKubernetes, ip.Status.Cluster) + assert.Equal(t, v1.TraitProfileKnative, ip.Status.Profile) + assert.Equal(t, v1.BuildStrategyPod, ip.Status.Build.BuildConfiguration.Strategy) + assert.Equal(t, v1.BuildOrderStrategyFIFO, ip.Status.Build.BuildConfiguration.OrderStrategy) + assert.True(t, ip.Status.Build.MaxRunningBuilds == 1) + assert.Equal(t, 3, len(ip.Status.Build.Maven.CLIOptions)) + assert.NotNil(t, ip.Status.Traits) + assert.NotNil(t, ip.Status.Traits.Logging) + assert.Equal(t, "DEBUG", ip.Status.Traits.Logging.Level) + assert.NotNil(t, ip.Status.Traits.Container) + assert.Equal(t, corev1.PullAlways, ip.Status.Traits.Container.ImagePullPolicy) + assert.Equal(t, "0.1", ip.Status.Traits.Container.LimitCPU) + assert.Equal(t, 3, len(ip.Status.Build.Maven.Properties)) + assert.Equal(t, "global_value1", ip.Status.Build.Maven.Properties["global_prop1"]) + assert.Equal(t, "local_value2", ip.Status.Build.Maven.Properties["global_prop2"]) + assert.Equal(t, "local_value1", ip.Status.Build.Maven.Properties["local_prop1"]) +} diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml new file mode 100644 index 0000000000..3e997b3cea --- /dev/null +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml @@ -0,0 +1,3559 @@ +# --------------------------------------------------------------------------- +# 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: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.6.1 + creationTimestamp: null + labels: + app: camel-k + name: integrationprofiles.camel.apache.org +spec: + group: camel.apache.org + names: + categories: + - kamel + - camel + kind: IntegrationProfile + listKind: IntegrationProfileList + plural: integrationprofiles + shortNames: + - ipr + singular: integrationprofile + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The integration profile phase + jsonPath: .status.phase + name: Phase + type: string + - description: The default runtime version + jsonPath: .status.build.runtimeVersion + name: Default runtime + type: string + name: v1 + schema: + openAPIV3Schema: + description: IntegrationProfile is the resource used to apply user defined + settings to the Camel K operator behavior. It defines the behavior of all + Custom Resources (`IntegrationKit`, `Integration`, `Kamelet`) in the given + namespace. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: IntegrationProfileSpec applies user defined settings to the + IntegrationProfile. + properties: + build: + description: specify how to build the Integration/IntegrationKits + properties: + baseImage: + description: a base image that can be used as base layer for all + images. It can be useful if you want to provide some custom + base image with further utility software + type: string + maven: + description: Maven configuration used to build the Camel/Camel-Quarkus + applications + properties: + caSecrets: + description: The Secrets name and key, containing the CA certificate(s) + used to connect to remote Maven repositories. It can contain + X.509 certificates, and PKCS#7 formatted certificate chains. + A JKS formatted keystore is automatically created to store + the CA certificate(s), and configured to be used as a trusted + certificate(s) by the Maven commands. Note that the root + CA certificates are also imported into the created keystore. + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: array + cliOptions: + description: The CLI options that are appended to the list + of arguments for Maven commands, e.g., `-V,--no-transfer-progress,-Dstyle.color=never`. + See https://maven.apache.org/ref/3.8.4/maven-embedder/cli.html. + items: + type: string + type: array + extension: + description: The Maven build extensions. See https://maven.apache.org/guides/mini/guide-using-extensions.html. + items: + description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) + Maven artifact. + properties: + artifactId: + description: Maven Artifact + type: string + classifier: + description: Maven Classifier + type: string + groupId: + description: Maven Group + type: string + type: + description: Maven Type + type: string + version: + description: Maven Version + type: string + required: + - artifactId + - groupId + type: object + type: array + localRepository: + description: The path of the local Maven repository. + type: string + profiles: + description: A reference to the ConfigMap or Secret key that + contains the Maven profile. + items: + description: ValueSource --. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: array + properties: + additionalProperties: + type: string + description: The Maven properties. + type: object + settings: + description: A reference to the ConfigMap or Secret key that + contains the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + settingsSecurity: + description: A reference to the ConfigMap or Secret key that + contains the security of the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: object + registry: + description: the image registry used to push/pull Integration + images + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate Authority + type: string + insecure: + description: if the container registry is insecure (ie, http + only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + runtimeProvider: + description: the runtime used. Likely Camel Quarkus (we used to + have main runtime which has been discontinued since version + 1.5) + type: string + runtimeVersion: + description: the Camel K Runtime dependency version + type: string + timeout: + description: how much time to wait before time out the pipeline + process + type: string + type: object + kamelet: + description: configuration to be executed to all Kamelets controlled + by this IntegrationProfile + properties: + repositories: + description: remote repository used to retrieve Kamelet catalog + items: + description: KameletRepositorySpec defines the location of the + Kamelet catalog to use. + properties: + uri: + description: the remote repository in the format github:ORG/REPO/PATH_TO_KAMELETS_FOLDER + type: string + type: object + type: array + type: object + traits: + description: list of traits to be executed for all the Integration/IntegrationKits + built from this IntegrationProfile + properties: + 3scale: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + addons: + additionalProperties: + description: AddonTrait represents the configuration of an addon + trait. + type: object + x-kubernetes-preserve-unknown-fields: true + description: The extension point with addon traits + type: object + affinity: + description: The configuration of Affinity trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodeAffinityLabels: + description: Defines a set of nodes the integration pod(s) + are eligible to be scheduled on, based on labels on the + node. + items: + type: string + type: array + podAffinity: + description: Always co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should be co-located with. + items: + type: string + type: array + podAntiAffinity: + description: Never co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAntiAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should not be co-located with. + items: + type: string + type: array + type: object + builder: + description: The configuration of Builder trait + properties: + annotations: + additionalProperties: + type: string + description: When using `pod` strategy, annotation to use + for the builder pod. + type: object + baseImage: + description: Specify a base image + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + incrementalImageBuild: + description: Use the incremental image build option, to reuse + existing containers (default `true`) + type: boolean + limitCPU: + description: 'When using `pod` strategy, the maximum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + limitMemory: + description: 'When using `pod` strategy, the maximum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + mavenProfiles: + description: 'A list of references pointing to configmaps/secrets + that contains a maven profile. The content of the maven + profile is expected to be a text containing a valid maven + profile starting with `` and ending with `` + that will be integrated as an inline profile in the POM. + Syntax: [configmap|secret]:name[/key], where name represents + the resource name, key optionally represents the resource + key to be filtered (default key value = profile.xml).' + items: + type: string + type: array + nodeSelector: + additionalProperties: + type: string + description: Defines a set of nodes the builder pod is eligible + to be scheduled on, based on labels on the node. + type: object + orderStrategy: + description: The build order strategy to use, either `dependencies`, + `fifo` or `sequential` (default `sequential`) + enum: + - dependencies + - fifo + - sequential + type: string + properties: + description: A list of properties to be provided to the build + task + items: + type: string + type: array + requestCPU: + description: 'When using `pod` strategy, the minimum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + requestMemory: + description: 'When using `pod` strategy, the minimum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + strategy: + description: The strategy to use, either `pod` or `routine` + (default `routine`) + enum: + - pod + - routine + type: string + tasks: + description: A list of tasks to be executed (available only + when using `pod` strategy) with format `;;`. + items: + type: string + type: array + tasksFilter: + description: A list of tasks sorted by the order of execution + in a csv format, ie, `,,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only with `pod` strategy. + type: string + tasksLimitCPU: + description: A list of limit cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksLimitMemory: + description: A list of limit memory configuration for the + specific task with format `:`. + items: + type: string + type: array + tasksRequestCPU: + description: A list of request cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksRequestMemory: + description: A list of request memory configuration for the + specific task with format `:`. + items: + type: string + type: array + verbose: + description: Enable verbose logging on build components that + support it (e.g. Kaniko build pod). Deprecated no longer + in use + type: boolean + type: object + camel: + description: The configuration of Camel trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + properties: + description: A list of properties to be provided to the Integration + runtime + items: + type: string + type: array + runtimeVersion: + description: The camel-k-runtime version to use for the integration. + It overrides the default version set in the Integration + Platform. + type: string + type: object + container: + description: The configuration of Container trait + properties: + auto: + description: To automatically enable the trait + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + expose: + description: Can be used to enable/disable exposure via kubernetes + Service. + type: boolean + image: + description: The main container image + type: string + imagePullPolicy: + description: 'The pull policy: Always|Never|IfNotPresent' + enum: + - Always + - Never + - IfNotPresent + type: string + limitCPU: + description: The maximum amount of CPU required. + type: string + limitMemory: + description: The maximum amount of memory required. + type: string + name: + description: The main container name. It's named `integration` + by default. + type: string + port: + description: To configure a different port exposed by the + container (default `8080`). + type: integer + portName: + description: To configure a different port name for the port + exposed by the container. It defaults to `http` only when + the `expose` parameter is true. + type: string + requestCPU: + description: The minimum amount of CPU required. + type: string + requestMemory: + description: The minimum amount of memory required. + type: string + servicePort: + description: To configure under which service port the container + port is to be exposed (default `80`). + type: integer + servicePortName: + description: To configure under which service port name the + container port is to be exposed (default `http`). + type: string + type: object + cron: + description: The configuration of Cron trait + properties: + activeDeadlineSeconds: + description: Specifies the duration in seconds, relative to + the start time, that the job may be continuously active + before it is considered to be failed. It defaults to 60s. + format: int64 + type: integer + auto: + description: "Automatically deploy the integration as CronJob + when all routes are either starting from a periodic consumer + (only `cron`, `timer` and `quartz` are supported) or a passive + consumer (e.g. `direct` is a passive consumer). \n It's + required that all periodic consumers have the same period, + and it can be expressed as cron schedule (e.g. `1m` can + be expressed as `0/1 * * * *`, while `35m` or `50s` cannot)." + type: boolean + backoffLimit: + description: Specifies the number of retries before marking + the job failed. It defaults to 2. + format: int32 + type: integer + components: + description: "A comma separated list of the Camel components + that need to be customized in order for them to work when + the schedule is triggered externally by Kubernetes. A specific + customizer is activated for each specified component. E.g. + for the `timer` component, the `cron-timer` customizer is + activated (it's present in the `org.apache.camel.k:camel-k-cron` + library). \n Supported components are currently: `cron`, + `timer` and `quartz`." + type: string + concurrencyPolicy: + description: 'Specifies how to treat concurrent executions + of a Job. Valid values are: - "Allow": allows CronJobs to + run concurrently; - "Forbid" (default): forbids concurrent + runs, skipping next run if previous run hasn''t finished + yet; - "Replace": cancels currently running job and replaces + it with a new one' + enum: + - Allow + - Forbid + - Replace + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + fallback: + description: Use the default Camel implementation of the `cron` + endpoint (`quartz`) instead of trying to materialize the + integration as Kubernetes CronJob. + type: boolean + schedule: + description: The CronJob schedule for the whole integration. + If multiple routes are declared, they must have the same + schedule for this mechanism to work correctly. + type: string + startingDeadlineSeconds: + description: Optional deadline in seconds for starting the + job if it misses scheduled time for any reason. Missed + jobs executions will be counted as failed ones. + format: int64 + type: integer + type: object + dependencies: + description: The configuration of Dependencies trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + deployer: + description: The configuration of Deployer trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + kind: + description: Allows to explicitly select the desired deployment + kind between `deployment`, `cron-job` or `knative-service` + when creating the resources for running the integration. + enum: + - deployment + - cron-job + - knative-service + type: string + useSSA: + description: Use server-side apply to update the owned resources + (default `true`). Note that it automatically falls back + to client-side patching, if SSA is not available, e.g., + on old Kubernetes clusters. + type: boolean + type: object + deployment: + description: The configuration of Deployment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + progressDeadlineSeconds: + description: The maximum time in seconds for the deployment + to make progress before it is considered to be failed. It + defaults to `60s`. + format: int32 + type: integer + rollingUpdateMaxSurge: + description: 'The maximum number of pods that can be scheduled + above the desired number of pods. Value can be an absolute + number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. Absolute number + is calculated from percentage by rounding up. Defaults to + `25%`.' + type: integer + rollingUpdateMaxUnavailable: + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute number + is calculated from percentage by rounding down. This can + not be 0 if MaxSurge is 0. Defaults to `25%`.' + type: integer + strategy: + description: The deployment strategy to use to replace existing + pods with new ones. + enum: + - Recreate + - RollingUpdate + type: string + type: object + environment: + description: The configuration of Environment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + containerMeta: + description: Enables injection of `NAMESPACE` and `POD_NAME` + environment variables (default `true`) + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + httpProxy: + description: Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and + `NO_PROXY` environment variables (default `true`) + type: boolean + vars: + description: A list of environment variables to be added to + the integration container. The syntax is KEY=VALUE, e.g., + `MY_VAR="my value"`. These take precedence over the previously + defined environment variables. + items: + type: string + type: array + type: object + error-handler: + description: The configuration of Error Handler trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + ref: + description: The error handler ref name provided or found + in application properties + type: string + type: object + gc: + description: The configuration of GC trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryCache: + description: 'Discovery client cache to be used, either `disabled`, + `disk` or `memory` (default `memory`). Deprecated: to be + removed from trait configuration.' + enum: + - disabled + - disk + - memory + type: string + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + health: + description: The configuration of Health trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + livenessFailureThreshold: + description: Minimum consecutive failures for the liveness + probe to be considered failed after having succeeded. + format: int32 + type: integer + livenessInitialDelay: + description: Number of seconds after the container has started + before the liveness probe is initiated. + format: int32 + type: integer + livenessPeriod: + description: How often to perform the liveness probe. + format: int32 + type: integer + livenessProbeEnabled: + description: Configures the liveness probe for the integration + container (default `false`). + type: boolean + livenessScheme: + description: Scheme to use when connecting to the liveness + probe (default `HTTP`). + type: string + livenessSuccessThreshold: + description: Minimum consecutive successes for the liveness + probe to be considered successful after having failed. + format: int32 + type: integer + livenessTimeout: + description: Number of seconds after which the liveness probe + times out. + format: int32 + type: integer + readinessFailureThreshold: + description: Minimum consecutive failures for the readiness + probe to be considered failed after having succeeded. + format: int32 + type: integer + readinessInitialDelay: + description: Number of seconds after the container has started + before the readiness probe is initiated. + format: int32 + type: integer + readinessPeriod: + description: How often to perform the readiness probe. + format: int32 + type: integer + readinessProbeEnabled: + description: Configures the readiness probe for the integration + container (default `true`). + type: boolean + readinessScheme: + description: Scheme to use when connecting to the readiness + probe (default `HTTP`). + type: string + readinessSuccessThreshold: + description: Minimum consecutive successes for the readiness + probe to be considered successful after having failed. + format: int32 + type: integer + readinessTimeout: + description: Number of seconds after which the readiness probe + times out. + format: int32 + type: integer + startupFailureThreshold: + description: Minimum consecutive failures for the startup + probe to be considered failed after having succeeded. + format: int32 + type: integer + startupInitialDelay: + description: Number of seconds after the container has started + before the startup probe is initiated. + format: int32 + type: integer + startupPeriod: + description: How often to perform the startup probe. + format: int32 + type: integer + startupProbeEnabled: + description: Configures the startup probe for the integration + container (default `false`). + type: boolean + startupScheme: + description: Scheme to use when connecting to the startup + probe (default `HTTP`). + type: string + startupSuccessThreshold: + description: Minimum consecutive successes for the startup + probe to be considered successful after having failed. + format: int32 + type: integer + startupTimeout: + description: Number of seconds after which the startup probe + times out. + format: int32 + type: integer + type: object + ingress: + description: The configuration of Ingress trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to the ingress. This can + be used to set controller specific annotations, e.g., when + using the NGINX Ingress controller: See https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md' + type: object + auto: + description: To automatically add an ingress whenever the + integration uses an HTTP endpoint consumer. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the ingress. + type: string + path: + description: To configure the path exposed by the ingress + (default `/`). + type: string + pathType: + description: To configure the path type exposed by the ingress. + One of `Exact`, `Prefix`, `ImplementationSpecific` (default + to `Prefix`). + enum: + - Exact + - Prefix + - ImplementationSpecific + type: string + type: object + istio: + description: The configuration of Istio trait + properties: + allow: + description: Configures a (comma-separated) list of CIDR subnets + that should not be intercepted by the Istio proxy (`10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` + by default). + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + inject: + description: Forces the value for labels `sidecar.istio.io/inject`. + By default the label is set to `true` on deployment and + not set on Knative Service. + type: boolean + type: object + jolokia: + description: The configuration of Jolokia trait + properties: + CACert: + description: The PEM encoded CA certification file path, used + to verify client certificates, applicable when `protocol` + is `https` and `use-ssl-client-authentication` is `true` + (default `/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt` + for OpenShift). + type: string + clientPrincipal: + description: The principal(s) which must be given in a client + certificate to allow access to the Jolokia endpoint, applicable + when `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `clientPrincipal=cn=system:master-proxy`, + `cn=hawtio-online.hawtio.svc` and `cn=fuse-console.fuse.svc` + for OpenShift). + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryEnabled: + description: Listen for multicast requests (default `false`) + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + extendedClientCheck: + description: Mandate the client certificate contains a client + flag in the extended key usage section, applicable when + `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `true` for OpenShift). + type: boolean + host: + description: The Host address to which the Jolokia agent should + bind to. If `"\*"` or `"0.0.0.0"` is given, the servers + binds to every network interface (default `"*"`). + type: string + options: + description: A list of additional Jolokia options as defined + in https://jolokia.org/reference/html/agents.html#agent-jvm-config[JVM + agent configuration options] + items: + type: string + type: array + password: + description: The password used for authentication, applicable + when the `user` option is set. + type: string + port: + description: The Jolokia endpoint port (default `8778`). + type: integer + protocol: + description: The protocol to use, either `http` or `https` + (default `https` for OpenShift) + type: string + useSSLClientAuthentication: + description: Whether client certificates should be used for + authentication (default `true` for OpenShift). + type: boolean + user: + description: The user to be used for authentication + type: string + type: object + jvm: + description: The configuration of JVM trait + properties: + classpath: + description: Additional JVM classpath (use `Linux` classpath + separator) + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + debug: + description: Activates remote debugging, so that a debugger + can be attached to the JVM, e.g., using port-forwarding + type: boolean + debugAddress: + description: Transport address at which to listen for the + newly launched JVM (default `*:5005`) + type: string + debugSuspend: + description: Suspends the target JVM immediately before the + main class is loaded + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + options: + description: A list of JVM options + items: + type: string + type: array + printCommand: + description: Prints the command used the start the JVM in + the container logs (default `true`) + type: boolean + type: object + kamelets: + description: The configuration of Kamelets trait + properties: + auto: + description: Automatically inject all referenced Kamelets + and their default configuration (enabled by default) + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + list: + description: Comma separated list of Kamelet names to load + into the current integration + type: string + mountPoint: + description: The directory where the application mounts and + reads Kamelet spec (default `/etc/camel/kamelets`) + type: string + type: object + keda: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + knative: + description: The configuration of Knative trait + properties: + auto: + description: Enable automatic discovery of all trait properties. + type: boolean + channelSinks: + description: List of channels used as destination of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + channelSources: + description: List of channels used as source of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + config: + description: Can be used to inject a Knative complete configuration + in JSON format. + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + endpointSinks: + description: List of endpoints used as destination of integration + routes. Can contain simple endpoint names or full Camel + URIs. + items: + type: string + type: array + endpointSources: + description: List of channels used as source of integration + routes. + items: + type: string + type: array + eventSinks: + description: List of event types that the integration will + produce. Can contain simple event types or full Camel URIs + (to use a specific broker). + items: + type: string + type: array + eventSources: + description: List of event types that the integration will + be subscribed to. Can contain simple event types or full + Camel URIs (to use a specific broker different from "default"). + items: + type: string + type: array + filterSourceChannels: + description: Enables filtering on events based on the header + "ce-knativehistory". Since this header has been removed + in newer versions of Knative, filtering is disabled by default. + type: boolean + namespaceLabel: + description: 'Enables the camel-k-operator to set the "bindings.knative.dev/include=true" + label to the namespace As Knative requires this label to + perform injection of K_SINK URL into the service. If this + is false, the integration pod may start and fail, read the + SinkBinding Knative documentation. (default: true)' + type: boolean + sinkBinding: + description: Allows binding the integration to a sink via + a Knative SinkBinding resource. This can be used when the + integration targets a single sink. It's enabled by default + when the integration targets a single sink (except when + the integration is owned by a Knative source). + type: boolean + type: object + knative-service: + description: The configuration of Knative Service trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set knative service specific annotations CLI usage + example: -t "knative-service.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + auto: + description: "Automatically deploy the integration as Knative + service when all conditions hold: \n * Integration is using + the Knative profile * All routes are either starting from + an HTTP based consumer or a passive consumer (e.g. `direct` + is a passive consumer)" + type: boolean + autoscalingMetric: + description: "Configures the Knative autoscaling metric property + (e.g. to set `concurrency` based or `cpu` based autoscaling). + \n Refer to the Knative documentation for more information." + type: string + autoscalingTarget: + description: "Sets the allowed concurrency level or CPU percentage + (depending on the autoscaling metric) for each Pod. \n Refer + to the Knative documentation for more information." + type: integer + class: + description: "Configures the Knative autoscaling class property + (e.g. to set `hpa.autoscaling.knative.dev` or `kpa.autoscaling.knative.dev` + autoscaling). \n Refer to the Knative documentation for + more information." + enum: + - kpa.autoscaling.knative.dev + - hpa.autoscaling.knative.dev + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxScale: + description: "An upper bound for the number of Pods that can + be running in parallel for the integration. Knative has + its own cap value that depends on the installation. \n Refer + to the Knative documentation for more information." + type: integer + minScale: + description: "The minimum number of Pods that should be running + at any time for the integration. It's **zero** by default, + meaning that the integration is scaled down to zero when + not used for a configured amount of time. \n Refer to the + Knative documentation for more information." + type: integer + rolloutDuration: + description: Enables to gradually shift traffic to the latest + Revision and sets the rollout duration. It's disabled by + default and must be expressed as a Golang `time.Duration` + string representation, rounded to a second precision. + type: string + visibility: + description: "Setting `cluster-local`, Knative service becomes + a private service. Specifically, this option applies the + `networking.knative.dev/visibility` label to Knative service. + \n Refer to the Knative documentation for more information." + enum: + - cluster-local + type: string + type: object + logging: + description: The configuration of Logging trait + properties: + color: + description: Colorize the log output + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + format: + description: Logs message format + type: string + json: + description: Output the logs in JSON + type: boolean + jsonPrettyPrint: + description: Enable "pretty printing" of the JSON logs + type: boolean + level: + description: Adjust the logging level (defaults to `INFO`) + enum: + - FATAL + - WARN + - INFO + - DEBUG + - TRACE + type: string + type: object + master: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + mount: + description: The configuration of Mount trait + properties: + configs: + description: 'A list of configuration pointing to configmap/secret. + The configuration are expected to be UTF-8 resources as + they are processed by runtime Camel Context and tried to + be parsed as property files. They are also made available + on the classpath in order to ease their usage directly from + the Route. Syntax: [configmap|secret]:name[/key], where + name represents the resource name and key optionally represents + the resource key to be filtered' + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + hotReload: + description: Enable "hot reload" when a secret/configmap mounted + is edited (default `false`). The configmap/secret must be + marked with `camel.apache.org/integration` label to be taken + in account. + type: boolean + resources: + description: 'A list of resources (text or binary content) + pointing to configmap/secret. The resources are expected + to be any resource type (text or binary content). The destination + path can be either a default location or any path specified + by the user. Syntax: [configmap|secret]:name[/key][@path], + where name represents the resource name, key optionally + represents the resource key to be filtered and path represents + the destination path' + items: + type: string + type: array + volumes: + description: 'A list of Persistent Volume Claims to be mounted. + Syntax: [pvcname:/container/path]' + items: + type: string + type: array + type: object + openapi: + description: The configuration of OpenAPI trait + properties: + configmaps: + description: The configmaps holding the spec of the OpenAPI + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + owner: + description: The configuration of Owner trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + targetAnnotations: + description: The set of annotations to be transferred + items: + type: string + type: array + targetLabels: + description: The set of labels to be transferred + items: + type: string + type: array + type: object + pdb: + description: The configuration of PDB trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxUnavailable: + description: The number of pods for the Integration that can + be unavailable after an eviction. It can be either an absolute + number or a percentage (default `1` if `min-available` is + also not set). Only one of `max-unavailable` and `min-available` + can be specified. + type: string + minAvailable: + description: The number of pods for the Integration that must + still be available after an eviction. It can be either an + absolute number or a percentage. Only one of `min-available` + and `max-unavailable` can be specified. + type: string + type: object + platform: + description: The configuration of Platform trait + properties: + auto: + description: 'To automatically detect from the environment + if a default platform can be created (it will be created + on OpenShift or when a registry address is set). Deprecated: + Platform is auto generated by the operator install procedure + - maintained for backward compatibility' + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + createDefault: + description: 'To create a default (empty) platform when the + platform is missing. Deprecated: Platform is auto generated + by the operator install procedure - maintained for backward + compatibility' + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + global: + description: 'Indicates if the platform should be created + globally in the case of global operator (default true). + Deprecated: Platform is auto generated by the operator install + procedure - maintained for backward compatibility' + type: boolean + type: object + pod: + description: The configuration of Pod trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + prometheus: + description: The configuration of Prometheus trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + podMonitor: + description: Whether a `PodMonitor` resource is created (default + `true`). + type: boolean + podMonitorLabels: + description: The `PodMonitor` resource labels, applicable + when `pod-monitor` is `true`. + items: + type: string + type: array + type: object + pull-secret: + description: The configuration of Pull Secret trait + properties: + auto: + description: Automatically configures the platform registry + secret on the pod if it is of type `kubernetes.io/dockerconfigjson`. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + imagePullerDelegation: + description: When using a global operator with a shared platform, + this enables delegation of the `system:image-puller` cluster + role on the operator namespace to the integration service + account. + type: boolean + secretName: + description: The pull secret name to set on the Pod. If left + empty this is automatically taken from the `IntegrationPlatform` + registry configuration. + type: string + type: object + quarkus: + description: The configuration of Quarkus trait + properties: + buildMode: + description: 'The Quarkus mode to run: either `jvm` or `native` + (default `jvm`). In case both `jvm` and `native` are specified, + two `IntegrationKit` resources are created, with the `native` + kit having precedence over the `jvm` one once ready.' + items: + description: QuarkusMode is the type of Quarkus build packaging. + enum: + - jvm + - native + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + nativeBaseImage: + description: The base image to use when running a native build + (default `quay.io/quarkus/quarkus-micro-image:2.0`) + type: string + nativeBuilderImage: + description: The image containing the tooling required for + a native build (by default it will use the one provided + in the runtime catalog) + type: string + packageTypes: + description: 'The Quarkus package types, `fast-jar` or `native` + (default `fast-jar`). In case both `fast-jar` and `native` + are specified, two `IntegrationKit` resources are created, + with the native kit having precedence over the `fast-jar` + one once ready. The order influences the resolution of the + current kit for the integration. The kit corresponding to + the first package type will be assigned to the integration + in case no existing kit that matches the integration exists. + Deprecated: use `build-mode` instead.' + items: + description: 'QuarkusPackageType is the type of Quarkus + build packaging. Deprecated: use `QuarkusMode` instead.' + enum: + - fast-jar + - native + type: string + type: array + type: object + registry: + description: The configuration of Registry trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + route: + description: The configuration of Route trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set route specific annotations For annotations options + see https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#route-specific-annotations + CLI usage example: -t "route.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the route. + type: string + tlsCACertificate: + description: "The TLS CA certificate contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsCACertificateSecret: + description: "The secret name and key reference to the TLS + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsCertificate: + description: "The TLS certificate contents. \n Refer to the + OpenShift route documentation for additional information." + type: string + tlsCertificateSecret: + description: "The secret name and key reference to the TLS + certificate. The format is \"secret-name[/key-name]\", the + value represents the secret name, if there is only one key + in the secret it will be read, otherwise you can set a key + name separated with a \"/\". \n Refer to the OpenShift route + documentation for additional information." + type: string + tlsDestinationCACertificate: + description: "The destination CA certificate provides the + contents of the ca certificate of the final destination. + \ When using reencrypt termination this file should be provided + in order to have routers use it for health checks on the + secure connection. If this field is not specified, the router + may provide its own destination CA and perform hostname + validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to automatically + verify. \n Refer to the OpenShift route documentation for + additional information." + type: string + tlsDestinationCACertificateSecret: + description: "The secret name and key reference to the destination + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsInsecureEdgeTerminationPolicy: + description: "To configure how to deal with insecure traffic, + e.g. `Allow`, `Disable` or `Redirect` traffic. \n Refer + to the OpenShift route documentation for additional information." + enum: + - None + - Allow + - Redirect + type: string + tlsKey: + description: "The TLS certificate key contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsKeySecret: + description: "The secret name and key reference to the TLS + certificate key. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsTermination: + description: "The TLS termination type, like `edge`, `passthrough` + or `reencrypt`. \n Refer to the OpenShift route documentation + for additional information." + enum: + - edge + - reencrypt + - passthrough + type: string + type: object + service: + description: The configuration of Service trait + properties: + auto: + description: To automatically detect from the code if a Service + needs to be created. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodePort: + description: 'Enable Service to be exposed as NodePort (default + `false`). Deprecated: Use service type instead.' + type: boolean + type: + description: The type of service to be used, either 'ClusterIP', + 'NodePort' or 'LoadBalancer'. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + type: object + service-binding: + description: The configuration of Service Binding trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + services: + description: List of Services in the form [[apigroup/]version:]kind:[namespace/]name + items: + type: string + type: array + type: object + strimzi: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + toleration: + description: The configuration of Toleration trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + taints: + description: The list of taints to tolerate, in the form `Key[=Value]:Effect[:Seconds]` + items: + type: string + type: array + type: object + tracing: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + type: object + type: object + status: + description: IntegrationProfileStatus defines the observed state of IntegrationProfile. + properties: + build: + description: specify how to build the Integration/IntegrationKits + properties: + baseImage: + description: a base image that can be used as base layer for all + images. It can be useful if you want to provide some custom + base image with further utility software + type: string + maven: + description: Maven configuration used to build the Camel/Camel-Quarkus + applications + properties: + caSecrets: + description: The Secrets name and key, containing the CA certificate(s) + used to connect to remote Maven repositories. It can contain + X.509 certificates, and PKCS#7 formatted certificate chains. + A JKS formatted keystore is automatically created to store + the CA certificate(s), and configured to be used as a trusted + certificate(s) by the Maven commands. Note that the root + CA certificates are also imported into the created keystore. + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + type: array + cliOptions: + description: The CLI options that are appended to the list + of arguments for Maven commands, e.g., `-V,--no-transfer-progress,-Dstyle.color=never`. + See https://maven.apache.org/ref/3.8.4/maven-embedder/cli.html. + items: + type: string + type: array + extension: + description: The Maven build extensions. See https://maven.apache.org/guides/mini/guide-using-extensions.html. + items: + description: MavenArtifact defines a GAV (Group:Artifact:Type:Version:Classifier) + Maven artifact. + properties: + artifactId: + description: Maven Artifact + type: string + classifier: + description: Maven Classifier + type: string + groupId: + description: Maven Group + type: string + type: + description: Maven Type + type: string + version: + description: Maven Version + type: string + required: + - artifactId + - groupId + type: object + type: array + localRepository: + description: The path of the local Maven repository. + type: string + profiles: + description: A reference to the ConfigMap or Secret key that + contains the Maven profile. + items: + description: ValueSource --. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: array + properties: + additionalProperties: + type: string + description: The Maven properties. + type: object + settings: + description: A reference to the ConfigMap or Secret key that + contains the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + settingsSecurity: + description: A reference to the ConfigMap or Secret key that + contains the security of the Maven settings. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + secretKeyRef: + description: Selects a key of a secret. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + type: object + type: object + registry: + description: the image registry used to push/pull Integration + images + properties: + address: + description: the URI to access + type: string + ca: + description: the configmap which stores the Certificate Authority + type: string + insecure: + description: if the container registry is insecure (ie, http + only) + type: boolean + organization: + description: the registry organization + type: string + secret: + description: the secret where credentials are stored + type: string + type: object + runtimeProvider: + description: the runtime used. Likely Camel Quarkus (we used to + have main runtime which has been discontinued since version + 1.5) + type: string + runtimeVersion: + description: the Camel K Runtime dependency version + type: string + timeout: + description: how much time to wait before time out the pipeline + process + type: string + type: object + conditions: + description: which are the conditions met (particularly useful when + in ERROR phase) + items: + description: IntegrationProfileCondition describes the state of + a resource at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human-readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of integration condition. + type: string + required: + - status + - type + type: object + type: array + kamelet: + description: configuration to be executed to all Kamelets controlled + by this IntegrationProfile + properties: + repositories: + description: remote repository used to retrieve Kamelet catalog + items: + description: KameletRepositorySpec defines the location of the + Kamelet catalog to use. + properties: + uri: + description: the remote repository in the format github:ORG/REPO/PATH_TO_KAMELETS_FOLDER + type: string + type: object + type: array + type: object + observedGeneration: + description: ObservedGeneration is the most recent generation observed + for this IntegrationProfile. + format: int64 + type: integer + phase: + description: defines in what phase the IntegrationProfile is found + type: string + traits: + description: list of traits to be executed for all the Integration/IntegrationKits + built from this IntegrationProfile + properties: + 3scale: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + addons: + additionalProperties: + description: AddonTrait represents the configuration of an addon + trait. + type: object + x-kubernetes-preserve-unknown-fields: true + description: The extension point with addon traits + type: object + affinity: + description: The configuration of Affinity trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodeAffinityLabels: + description: Defines a set of nodes the integration pod(s) + are eligible to be scheduled on, based on labels on the + node. + items: + type: string + type: array + podAffinity: + description: Always co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should be co-located with. + items: + type: string + type: array + podAntiAffinity: + description: Never co-locates multiple replicas of the integration + in the same node (default `false`). + type: boolean + podAntiAffinityLabels: + description: Defines a set of pods (namely those matching + the label selector, relative to the given namespace) that + the integration pod(s) should not be co-located with. + items: + type: string + type: array + type: object + builder: + description: The configuration of Builder trait + properties: + annotations: + additionalProperties: + type: string + description: When using `pod` strategy, annotation to use + for the builder pod. + type: object + baseImage: + description: Specify a base image + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + incrementalImageBuild: + description: Use the incremental image build option, to reuse + existing containers (default `true`) + type: boolean + limitCPU: + description: 'When using `pod` strategy, the maximum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + limitMemory: + description: 'When using `pod` strategy, the maximum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + mavenProfiles: + description: 'A list of references pointing to configmaps/secrets + that contains a maven profile. The content of the maven + profile is expected to be a text containing a valid maven + profile starting with `` and ending with `` + that will be integrated as an inline profile in the POM. + Syntax: [configmap|secret]:name[/key], where name represents + the resource name, key optionally represents the resource + key to be filtered (default key value = profile.xml).' + items: + type: string + type: array + nodeSelector: + additionalProperties: + type: string + description: Defines a set of nodes the builder pod is eligible + to be scheduled on, based on labels on the node. + type: object + orderStrategy: + description: The build order strategy to use, either `dependencies`, + `fifo` or `sequential` (default `sequential`) + enum: + - dependencies + - fifo + - sequential + type: string + properties: + description: A list of properties to be provided to the build + task + items: + type: string + type: array + requestCPU: + description: 'When using `pod` strategy, the minimum amount + of CPU required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + requestMemory: + description: 'When using `pod` strategy, the minimum amount + of memory required by the pod builder. Deprecated: use TasksRequestCPU + instead with task name `builder`.' + type: string + strategy: + description: The strategy to use, either `pod` or `routine` + (default `routine`) + enum: + - pod + - routine + type: string + tasks: + description: A list of tasks to be executed (available only + when using `pod` strategy) with format `;;`. + items: + type: string + type: array + tasksFilter: + description: A list of tasks sorted by the order of execution + in a csv format, ie, `,,...`. Mind + that you must include also the operator tasks (`builder`, + `quarkus-native`, `package`, `jib`, `spectrum`, `s2i`) if + you need to execute them. Useful only with `pod` strategy. + type: string + tasksLimitCPU: + description: A list of limit cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksLimitMemory: + description: A list of limit memory configuration for the + specific task with format `:`. + items: + type: string + type: array + tasksRequestCPU: + description: A list of request cpu configuration for the specific + task with format `:`. + items: + type: string + type: array + tasksRequestMemory: + description: A list of request memory configuration for the + specific task with format `:`. + items: + type: string + type: array + verbose: + description: Enable verbose logging on build components that + support it (e.g. Kaniko build pod). Deprecated no longer + in use + type: boolean + type: object + camel: + description: The configuration of Camel trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + properties: + description: A list of properties to be provided to the Integration + runtime + items: + type: string + type: array + runtimeVersion: + description: The camel-k-runtime version to use for the integration. + It overrides the default version set in the Integration + Platform. + type: string + type: object + container: + description: The configuration of Container trait + properties: + auto: + description: To automatically enable the trait + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + expose: + description: Can be used to enable/disable exposure via kubernetes + Service. + type: boolean + image: + description: The main container image + type: string + imagePullPolicy: + description: 'The pull policy: Always|Never|IfNotPresent' + enum: + - Always + - Never + - IfNotPresent + type: string + limitCPU: + description: The maximum amount of CPU required. + type: string + limitMemory: + description: The maximum amount of memory required. + type: string + name: + description: The main container name. It's named `integration` + by default. + type: string + port: + description: To configure a different port exposed by the + container (default `8080`). + type: integer + portName: + description: To configure a different port name for the port + exposed by the container. It defaults to `http` only when + the `expose` parameter is true. + type: string + requestCPU: + description: The minimum amount of CPU required. + type: string + requestMemory: + description: The minimum amount of memory required. + type: string + servicePort: + description: To configure under which service port the container + port is to be exposed (default `80`). + type: integer + servicePortName: + description: To configure under which service port name the + container port is to be exposed (default `http`). + type: string + type: object + cron: + description: The configuration of Cron trait + properties: + activeDeadlineSeconds: + description: Specifies the duration in seconds, relative to + the start time, that the job may be continuously active + before it is considered to be failed. It defaults to 60s. + format: int64 + type: integer + auto: + description: "Automatically deploy the integration as CronJob + when all routes are either starting from a periodic consumer + (only `cron`, `timer` and `quartz` are supported) or a passive + consumer (e.g. `direct` is a passive consumer). \n It's + required that all periodic consumers have the same period, + and it can be expressed as cron schedule (e.g. `1m` can + be expressed as `0/1 * * * *`, while `35m` or `50s` cannot)." + type: boolean + backoffLimit: + description: Specifies the number of retries before marking + the job failed. It defaults to 2. + format: int32 + type: integer + components: + description: "A comma separated list of the Camel components + that need to be customized in order for them to work when + the schedule is triggered externally by Kubernetes. A specific + customizer is activated for each specified component. E.g. + for the `timer` component, the `cron-timer` customizer is + activated (it's present in the `org.apache.camel.k:camel-k-cron` + library). \n Supported components are currently: `cron`, + `timer` and `quartz`." + type: string + concurrencyPolicy: + description: 'Specifies how to treat concurrent executions + of a Job. Valid values are: - "Allow": allows CronJobs to + run concurrently; - "Forbid" (default): forbids concurrent + runs, skipping next run if previous run hasn''t finished + yet; - "Replace": cancels currently running job and replaces + it with a new one' + enum: + - Allow + - Forbid + - Replace + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + fallback: + description: Use the default Camel implementation of the `cron` + endpoint (`quartz`) instead of trying to materialize the + integration as Kubernetes CronJob. + type: boolean + schedule: + description: The CronJob schedule for the whole integration. + If multiple routes are declared, they must have the same + schedule for this mechanism to work correctly. + type: string + startingDeadlineSeconds: + description: Optional deadline in seconds for starting the + job if it misses scheduled time for any reason. Missed + jobs executions will be counted as failed ones. + format: int64 + type: integer + type: object + dependencies: + description: The configuration of Dependencies trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + deployer: + description: The configuration of Deployer trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + kind: + description: Allows to explicitly select the desired deployment + kind between `deployment`, `cron-job` or `knative-service` + when creating the resources for running the integration. + enum: + - deployment + - cron-job + - knative-service + type: string + useSSA: + description: Use server-side apply to update the owned resources + (default `true`). Note that it automatically falls back + to client-side patching, if SSA is not available, e.g., + on old Kubernetes clusters. + type: boolean + type: object + deployment: + description: The configuration of Deployment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + progressDeadlineSeconds: + description: The maximum time in seconds for the deployment + to make progress before it is considered to be failed. It + defaults to `60s`. + format: int32 + type: integer + rollingUpdateMaxSurge: + description: 'The maximum number of pods that can be scheduled + above the desired number of pods. Value can be an absolute + number (ex: 5) or a percentage of desired pods (ex: 10%). + This can not be 0 if MaxUnavailable is 0. Absolute number + is calculated from percentage by rounding up. Defaults to + `25%`.' + type: integer + rollingUpdateMaxUnavailable: + description: 'The maximum number of pods that can be unavailable + during the update. Value can be an absolute number (ex: + 5) or a percentage of desired pods (ex: 10%). Absolute number + is calculated from percentage by rounding down. This can + not be 0 if MaxSurge is 0. Defaults to `25%`.' + type: integer + strategy: + description: The deployment strategy to use to replace existing + pods with new ones. + enum: + - Recreate + - RollingUpdate + type: string + type: object + environment: + description: The configuration of Environment trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + containerMeta: + description: Enables injection of `NAMESPACE` and `POD_NAME` + environment variables (default `true`) + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + httpProxy: + description: Propagates the `HTTP_PROXY`, `HTTPS_PROXY` and + `NO_PROXY` environment variables (default `true`) + type: boolean + vars: + description: A list of environment variables to be added to + the integration container. The syntax is KEY=VALUE, e.g., + `MY_VAR="my value"`. These take precedence over the previously + defined environment variables. + items: + type: string + type: array + type: object + error-handler: + description: The configuration of Error Handler trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + ref: + description: The error handler ref name provided or found + in application properties + type: string + type: object + gc: + description: The configuration of GC trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryCache: + description: 'Discovery client cache to be used, either `disabled`, + `disk` or `memory` (default `memory`). Deprecated: to be + removed from trait configuration.' + enum: + - disabled + - disk + - memory + type: string + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + health: + description: The configuration of Health trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + livenessFailureThreshold: + description: Minimum consecutive failures for the liveness + probe to be considered failed after having succeeded. + format: int32 + type: integer + livenessInitialDelay: + description: Number of seconds after the container has started + before the liveness probe is initiated. + format: int32 + type: integer + livenessPeriod: + description: How often to perform the liveness probe. + format: int32 + type: integer + livenessProbeEnabled: + description: Configures the liveness probe for the integration + container (default `false`). + type: boolean + livenessScheme: + description: Scheme to use when connecting to the liveness + probe (default `HTTP`). + type: string + livenessSuccessThreshold: + description: Minimum consecutive successes for the liveness + probe to be considered successful after having failed. + format: int32 + type: integer + livenessTimeout: + description: Number of seconds after which the liveness probe + times out. + format: int32 + type: integer + readinessFailureThreshold: + description: Minimum consecutive failures for the readiness + probe to be considered failed after having succeeded. + format: int32 + type: integer + readinessInitialDelay: + description: Number of seconds after the container has started + before the readiness probe is initiated. + format: int32 + type: integer + readinessPeriod: + description: How often to perform the readiness probe. + format: int32 + type: integer + readinessProbeEnabled: + description: Configures the readiness probe for the integration + container (default `true`). + type: boolean + readinessScheme: + description: Scheme to use when connecting to the readiness + probe (default `HTTP`). + type: string + readinessSuccessThreshold: + description: Minimum consecutive successes for the readiness + probe to be considered successful after having failed. + format: int32 + type: integer + readinessTimeout: + description: Number of seconds after which the readiness probe + times out. + format: int32 + type: integer + startupFailureThreshold: + description: Minimum consecutive failures for the startup + probe to be considered failed after having succeeded. + format: int32 + type: integer + startupInitialDelay: + description: Number of seconds after the container has started + before the startup probe is initiated. + format: int32 + type: integer + startupPeriod: + description: How often to perform the startup probe. + format: int32 + type: integer + startupProbeEnabled: + description: Configures the startup probe for the integration + container (default `false`). + type: boolean + startupScheme: + description: Scheme to use when connecting to the startup + probe (default `HTTP`). + type: string + startupSuccessThreshold: + description: Minimum consecutive successes for the startup + probe to be considered successful after having failed. + format: int32 + type: integer + startupTimeout: + description: Number of seconds after which the startup probe + times out. + format: int32 + type: integer + type: object + ingress: + description: The configuration of Ingress trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to the ingress. This can + be used to set controller specific annotations, e.g., when + using the NGINX Ingress controller: See https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/annotations.md' + type: object + auto: + description: To automatically add an ingress whenever the + integration uses an HTTP endpoint consumer. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the ingress. + type: string + path: + description: To configure the path exposed by the ingress + (default `/`). + type: string + pathType: + description: To configure the path type exposed by the ingress. + One of `Exact`, `Prefix`, `ImplementationSpecific` (default + to `Prefix`). + enum: + - Exact + - Prefix + - ImplementationSpecific + type: string + type: object + istio: + description: The configuration of Istio trait + properties: + allow: + description: Configures a (comma-separated) list of CIDR subnets + that should not be intercepted by the Istio proxy (`10.0.0.0/8,172.16.0.0/12,192.168.0.0/16` + by default). + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + inject: + description: Forces the value for labels `sidecar.istio.io/inject`. + By default the label is set to `true` on deployment and + not set on Knative Service. + type: boolean + type: object + jolokia: + description: The configuration of Jolokia trait + properties: + CACert: + description: The PEM encoded CA certification file path, used + to verify client certificates, applicable when `protocol` + is `https` and `use-ssl-client-authentication` is `true` + (default `/var/run/secrets/kubernetes.io/serviceaccount/service-ca.crt` + for OpenShift). + type: string + clientPrincipal: + description: The principal(s) which must be given in a client + certificate to allow access to the Jolokia endpoint, applicable + when `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `clientPrincipal=cn=system:master-proxy`, + `cn=hawtio-online.hawtio.svc` and `cn=fuse-console.fuse.svc` + for OpenShift). + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + discoveryEnabled: + description: Listen for multicast requests (default `false`) + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + extendedClientCheck: + description: Mandate the client certificate contains a client + flag in the extended key usage section, applicable when + `protocol` is `https` and `use-ssl-client-authentication` + is `true` (default `true` for OpenShift). + type: boolean + host: + description: The Host address to which the Jolokia agent should + bind to. If `"\*"` or `"0.0.0.0"` is given, the servers + binds to every network interface (default `"*"`). + type: string + options: + description: A list of additional Jolokia options as defined + in https://jolokia.org/reference/html/agents.html#agent-jvm-config[JVM + agent configuration options] + items: + type: string + type: array + password: + description: The password used for authentication, applicable + when the `user` option is set. + type: string + port: + description: The Jolokia endpoint port (default `8778`). + type: integer + protocol: + description: The protocol to use, either `http` or `https` + (default `https` for OpenShift) + type: string + useSSLClientAuthentication: + description: Whether client certificates should be used for + authentication (default `true` for OpenShift). + type: boolean + user: + description: The user to be used for authentication + type: string + type: object + jvm: + description: The configuration of JVM trait + properties: + classpath: + description: Additional JVM classpath (use `Linux` classpath + separator) + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + debug: + description: Activates remote debugging, so that a debugger + can be attached to the JVM, e.g., using port-forwarding + type: boolean + debugAddress: + description: Transport address at which to listen for the + newly launched JVM (default `*:5005`) + type: string + debugSuspend: + description: Suspends the target JVM immediately before the + main class is loaded + type: boolean + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + options: + description: A list of JVM options + items: + type: string + type: array + printCommand: + description: Prints the command used the start the JVM in + the container logs (default `true`) + type: boolean + type: object + kamelets: + description: The configuration of Kamelets trait + properties: + auto: + description: Automatically inject all referenced Kamelets + and their default configuration (enabled by default) + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + list: + description: Comma separated list of Kamelet names to load + into the current integration + type: string + mountPoint: + description: The directory where the application mounts and + reads Kamelet spec (default `/etc/camel/kamelets`) + type: string + type: object + keda: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + knative: + description: The configuration of Knative trait + properties: + auto: + description: Enable automatic discovery of all trait properties. + type: boolean + channelSinks: + description: List of channels used as destination of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + channelSources: + description: List of channels used as source of integration + routes. Can contain simple channel names or full Camel URIs. + items: + type: string + type: array + config: + description: Can be used to inject a Knative complete configuration + in JSON format. + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + endpointSinks: + description: List of endpoints used as destination of integration + routes. Can contain simple endpoint names or full Camel + URIs. + items: + type: string + type: array + endpointSources: + description: List of channels used as source of integration + routes. + items: + type: string + type: array + eventSinks: + description: List of event types that the integration will + produce. Can contain simple event types or full Camel URIs + (to use a specific broker). + items: + type: string + type: array + eventSources: + description: List of event types that the integration will + be subscribed to. Can contain simple event types or full + Camel URIs (to use a specific broker different from "default"). + items: + type: string + type: array + filterSourceChannels: + description: Enables filtering on events based on the header + "ce-knativehistory". Since this header has been removed + in newer versions of Knative, filtering is disabled by default. + type: boolean + namespaceLabel: + description: 'Enables the camel-k-operator to set the "bindings.knative.dev/include=true" + label to the namespace As Knative requires this label to + perform injection of K_SINK URL into the service. If this + is false, the integration pod may start and fail, read the + SinkBinding Knative documentation. (default: true)' + type: boolean + sinkBinding: + description: Allows binding the integration to a sink via + a Knative SinkBinding resource. This can be used when the + integration targets a single sink. It's enabled by default + when the integration targets a single sink (except when + the integration is owned by a Knative source). + type: boolean + type: object + knative-service: + description: The configuration of Knative Service trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set knative service specific annotations CLI usage + example: -t "knative-service.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + auto: + description: "Automatically deploy the integration as Knative + service when all conditions hold: \n * Integration is using + the Knative profile * All routes are either starting from + an HTTP based consumer or a passive consumer (e.g. `direct` + is a passive consumer)" + type: boolean + autoscalingMetric: + description: "Configures the Knative autoscaling metric property + (e.g. to set `concurrency` based or `cpu` based autoscaling). + \n Refer to the Knative documentation for more information." + type: string + autoscalingTarget: + description: "Sets the allowed concurrency level or CPU percentage + (depending on the autoscaling metric) for each Pod. \n Refer + to the Knative documentation for more information." + type: integer + class: + description: "Configures the Knative autoscaling class property + (e.g. to set `hpa.autoscaling.knative.dev` or `kpa.autoscaling.knative.dev` + autoscaling). \n Refer to the Knative documentation for + more information." + enum: + - kpa.autoscaling.knative.dev + - hpa.autoscaling.knative.dev + type: string + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxScale: + description: "An upper bound for the number of Pods that can + be running in parallel for the integration. Knative has + its own cap value that depends on the installation. \n Refer + to the Knative documentation for more information." + type: integer + minScale: + description: "The minimum number of Pods that should be running + at any time for the integration. It's **zero** by default, + meaning that the integration is scaled down to zero when + not used for a configured amount of time. \n Refer to the + Knative documentation for more information." + type: integer + rolloutDuration: + description: Enables to gradually shift traffic to the latest + Revision and sets the rollout duration. It's disabled by + default and must be expressed as a Golang `time.Duration` + string representation, rounded to a second precision. + type: string + visibility: + description: "Setting `cluster-local`, Knative service becomes + a private service. Specifically, this option applies the + `networking.knative.dev/visibility` label to Knative service. + \n Refer to the Knative documentation for more information." + enum: + - cluster-local + type: string + type: object + logging: + description: The configuration of Logging trait + properties: + color: + description: Colorize the log output + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + format: + description: Logs message format + type: string + json: + description: Output the logs in JSON + type: boolean + jsonPrettyPrint: + description: Enable "pretty printing" of the JSON logs + type: boolean + level: + description: Adjust the logging level (defaults to `INFO`) + enum: + - FATAL + - WARN + - INFO + - DEBUG + - TRACE + type: string + type: object + master: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + mount: + description: The configuration of Mount trait + properties: + configs: + description: 'A list of configuration pointing to configmap/secret. + The configuration are expected to be UTF-8 resources as + they are processed by runtime Camel Context and tried to + be parsed as property files. They are also made available + on the classpath in order to ease their usage directly from + the Route. Syntax: [configmap|secret]:name[/key], where + name represents the resource name and key optionally represents + the resource key to be filtered' + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + hotReload: + description: Enable "hot reload" when a secret/configmap mounted + is edited (default `false`). The configmap/secret must be + marked with `camel.apache.org/integration` label to be taken + in account. + type: boolean + resources: + description: 'A list of resources (text or binary content) + pointing to configmap/secret. The resources are expected + to be any resource type (text or binary content). The destination + path can be either a default location or any path specified + by the user. Syntax: [configmap|secret]:name[/key][@path], + where name represents the resource name, key optionally + represents the resource key to be filtered and path represents + the destination path' + items: + type: string + type: array + volumes: + description: 'A list of Persistent Volume Claims to be mounted. + Syntax: [pvcname:/container/path]' + items: + type: string + type: array + type: object + openapi: + description: The configuration of OpenAPI trait + properties: + configmaps: + description: The configmaps holding the spec of the OpenAPI + items: + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + type: object + owner: + description: The configuration of Owner trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + targetAnnotations: + description: The set of annotations to be transferred + items: + type: string + type: array + targetLabels: + description: The set of labels to be transferred + items: + type: string + type: array + type: object + pdb: + description: The configuration of PDB trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + maxUnavailable: + description: The number of pods for the Integration that can + be unavailable after an eviction. It can be either an absolute + number or a percentage (default `1` if `min-available` is + also not set). Only one of `max-unavailable` and `min-available` + can be specified. + type: string + minAvailable: + description: The number of pods for the Integration that must + still be available after an eviction. It can be either an + absolute number or a percentage. Only one of `min-available` + and `max-unavailable` can be specified. + type: string + type: object + platform: + description: The configuration of Platform trait + properties: + auto: + description: 'To automatically detect from the environment + if a default platform can be created (it will be created + on OpenShift or when a registry address is set). Deprecated: + Platform is auto generated by the operator install procedure + - maintained for backward compatibility' + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + createDefault: + description: 'To create a default (empty) platform when the + platform is missing. Deprecated: Platform is auto generated + by the operator install procedure - maintained for backward + compatibility' + type: boolean + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + global: + description: 'Indicates if the platform should be created + globally in the case of global operator (default true). + Deprecated: Platform is auto generated by the operator install + procedure - maintained for backward compatibility' + type: boolean + type: object + pod: + description: The configuration of Pod trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + prometheus: + description: The configuration of Prometheus trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + podMonitor: + description: Whether a `PodMonitor` resource is created (default + `true`). + type: boolean + podMonitorLabels: + description: The `PodMonitor` resource labels, applicable + when `pod-monitor` is `true`. + items: + type: string + type: array + type: object + pull-secret: + description: The configuration of Pull Secret trait + properties: + auto: + description: Automatically configures the platform registry + secret on the pod if it is of type `kubernetes.io/dockerconfigjson`. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + imagePullerDelegation: + description: When using a global operator with a shared platform, + this enables delegation of the `system:image-puller` cluster + role on the operator namespace to the integration service + account. + type: boolean + secretName: + description: The pull secret name to set on the Pod. If left + empty this is automatically taken from the `IntegrationPlatform` + registry configuration. + type: string + type: object + quarkus: + description: The configuration of Quarkus trait + properties: + buildMode: + description: 'The Quarkus mode to run: either `jvm` or `native` + (default `jvm`). In case both `jvm` and `native` are specified, + two `IntegrationKit` resources are created, with the `native` + kit having precedence over the `jvm` one once ready.' + items: + description: QuarkusMode is the type of Quarkus build packaging. + enum: + - jvm + - native + type: string + type: array + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: 'Deprecated: no longer in use.' + type: boolean + nativeBaseImage: + description: The base image to use when running a native build + (default `quay.io/quarkus/quarkus-micro-image:2.0`) + type: string + nativeBuilderImage: + description: The image containing the tooling required for + a native build (by default it will use the one provided + in the runtime catalog) + type: string + packageTypes: + description: 'The Quarkus package types, `fast-jar` or `native` + (default `fast-jar`). In case both `fast-jar` and `native` + are specified, two `IntegrationKit` resources are created, + with the native kit having precedence over the `fast-jar` + one once ready. The order influences the resolution of the + current kit for the integration. The kit corresponding to + the first package type will be assigned to the integration + in case no existing kit that matches the integration exists. + Deprecated: use `build-mode` instead.' + items: + description: 'QuarkusPackageType is the type of Quarkus + build packaging. Deprecated: use `QuarkusMode` instead.' + enum: + - fast-jar + - native + type: string + type: array + type: object + registry: + description: The configuration of Registry trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + type: object + route: + description: The configuration of Route trait + properties: + annotations: + additionalProperties: + type: string + description: 'The annotations added to route. This can be + used to set route specific annotations For annotations options + see https://docs.openshift.com/container-platform/3.11/architecture/networking/routes.html#route-specific-annotations + CLI usage example: -t "route.annotations.''haproxy.router.openshift.io/balance''=true"' + type: object + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + host: + description: To configure the host exposed by the route. + type: string + tlsCACertificate: + description: "The TLS CA certificate contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsCACertificateSecret: + description: "The secret name and key reference to the TLS + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsCertificate: + description: "The TLS certificate contents. \n Refer to the + OpenShift route documentation for additional information." + type: string + tlsCertificateSecret: + description: "The secret name and key reference to the TLS + certificate. The format is \"secret-name[/key-name]\", the + value represents the secret name, if there is only one key + in the secret it will be read, otherwise you can set a key + name separated with a \"/\". \n Refer to the OpenShift route + documentation for additional information." + type: string + tlsDestinationCACertificate: + description: "The destination CA certificate provides the + contents of the ca certificate of the final destination. + \ When using reencrypt termination this file should be provided + in order to have routers use it for health checks on the + secure connection. If this field is not specified, the router + may provide its own destination CA and perform hostname + validation using the short service name (service.namespace.svc), + which allows infrastructure generated certificates to automatically + verify. \n Refer to the OpenShift route documentation for + additional information." + type: string + tlsDestinationCACertificateSecret: + description: "The secret name and key reference to the destination + CA certificate. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsInsecureEdgeTerminationPolicy: + description: "To configure how to deal with insecure traffic, + e.g. `Allow`, `Disable` or `Redirect` traffic. \n Refer + to the OpenShift route documentation for additional information." + enum: + - None + - Allow + - Redirect + type: string + tlsKey: + description: "The TLS certificate key contents. \n Refer to + the OpenShift route documentation for additional information." + type: string + tlsKeySecret: + description: "The secret name and key reference to the TLS + certificate key. The format is \"secret-name[/key-name]\", + the value represents the secret name, if there is only one + key in the secret it will be read, otherwise you can set + a key name separated with a \"/\". \n Refer to the OpenShift + route documentation for additional information." + type: string + tlsTermination: + description: "The TLS termination type, like `edge`, `passthrough` + or `reencrypt`. \n Refer to the OpenShift route documentation + for additional information." + enum: + - edge + - reencrypt + - passthrough + type: string + type: object + service: + description: The configuration of Service trait + properties: + auto: + description: To automatically detect from the code if a Service + needs to be created. + type: boolean + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + nodePort: + description: 'Enable Service to be exposed as NodePort (default + `false`). Deprecated: Use service type instead.' + type: boolean + type: + description: The type of service to be used, either 'ClusterIP', + 'NodePort' or 'LoadBalancer'. + enum: + - ClusterIP + - NodePort + - LoadBalancer + type: string + type: object + service-binding: + description: The configuration of Service Binding trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + services: + description: List of Services in the form [[apigroup/]version:]kind:[namespace/]name + items: + type: string + type: array + type: object + strimzi: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + toleration: + description: The configuration of Toleration trait + properties: + configuration: + description: 'Legacy trait configuration parameters. Deprecated: + for backward compatibility.' + type: object + x-kubernetes-preserve-unknown-fields: true + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + taints: + description: The list of taints to tolerate, in the form `Key[=Value]:Effect[:Seconds]` + items: + type: string + type: array + type: object + tracing: + description: 'Deprecated: for backward compatibility.' + properties: + configuration: + description: TraitConfiguration parameters configuration + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - configuration + type: object + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/pkg/resources/config/crd/kustomization.yaml b/pkg/resources/config/crd/kustomization.yaml index 6941bdbadc..82a770e6ce 100644 --- a/pkg/resources/config/crd/kustomization.yaml +++ b/pkg/resources/config/crd/kustomization.yaml @@ -22,6 +22,7 @@ resources: - bases/camel.apache.org_camelcatalogs.yaml - bases/camel.apache.org_integrationkits.yaml - bases/camel.apache.org_integrationplatforms.yaml +- bases/camel.apache.org_integrationprofiles.yaml - bases/camel.apache.org_integrations.yaml - bases/camel.apache.org_kamelets.yaml - bases/camel.apache.org_kameletbindings.yaml diff --git a/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml b/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml index d7ee2fa399..ac33e942eb 100644 --- a/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml +++ b/pkg/resources/config/rbac/descoped/operator-cluster-role.yaml @@ -29,6 +29,7 @@ rules: - camelcatalogs - integrationkits - integrationplatforms + - integrationprofiles - integrations - pipes # Deprecated: kameletbindings CR @@ -54,6 +55,7 @@ rules: - camelcatalogs/status - integrationkits/status - integrationplatforms/status + - integrationprofiles/status - integrations/scale - integrations/status - pipes/status diff --git a/pkg/resources/config/rbac/namespaced/operator-role.yaml b/pkg/resources/config/rbac/namespaced/operator-role.yaml index 0f364463e4..391a76291c 100644 --- a/pkg/resources/config/rbac/namespaced/operator-role.yaml +++ b/pkg/resources/config/rbac/namespaced/operator-role.yaml @@ -29,6 +29,7 @@ rules: - camelcatalogs - integrationkits - integrationplatforms + - integrationprofiles - integrations - pipes # Deprecated: kameletbindings CR @@ -55,6 +56,7 @@ rules: - camelcatalogs/status - integrationkits/status - integrationplatforms/status + - integrationprofiles/status - integrations/scale - integrations/status - pipes/status diff --git a/pkg/resources/config/rbac/openshift/descoped/operator-cluster-role-openshift.yaml b/pkg/resources/config/rbac/openshift/descoped/operator-cluster-role-openshift.yaml index 5589d77933..d501b859c8 100644 --- a/pkg/resources/config/rbac/openshift/descoped/operator-cluster-role-openshift.yaml +++ b/pkg/resources/config/rbac/openshift/descoped/operator-cluster-role-openshift.yaml @@ -28,6 +28,7 @@ rules: - builds/finalizers - integrationkits/finalizers - integrationplatforms/finalizers + - integrationprofiles/finalizers - integrations/finalizers - pipes/finalizers - kameletbindings/finalizers diff --git a/pkg/resources/config/rbac/openshift/namespaced/operator-role-openshift.yaml b/pkg/resources/config/rbac/openshift/namespaced/operator-role-openshift.yaml index 4eccaee704..0d450dcea9 100644 --- a/pkg/resources/config/rbac/openshift/namespaced/operator-role-openshift.yaml +++ b/pkg/resources/config/rbac/openshift/namespaced/operator-role-openshift.yaml @@ -28,6 +28,7 @@ rules: - builds/finalizers - integrationkits/finalizers - integrationplatforms/finalizers + - integrationprofiles/finalizers - integrations/finalizers - pipes/finalizers - kameletbindings/finalizers diff --git a/pkg/resources/config/rbac/user-cluster-role.yaml b/pkg/resources/config/rbac/user-cluster-role.yaml index aef6bee1c1..c6a8c0086d 100644 --- a/pkg/resources/config/rbac/user-cluster-role.yaml +++ b/pkg/resources/config/rbac/user-cluster-role.yaml @@ -32,6 +32,7 @@ rules: - camelcatalogs - integrationkits - integrationplatforms + - integrationprofiles - integrations - pipes # Deprecated: kameletbindings CR @@ -53,6 +54,7 @@ rules: - camelcatalogs/status - integrationkits/status - integrationplatforms/status + - integrationprofiles/status - integrations/scale - integrations/status - pipes/scale diff --git a/pkg/resources/config/samples/bases/camel_v1_integrationprofile.yaml b/pkg/resources/config/samples/bases/camel_v1_integrationprofile.yaml new file mode 100644 index 0000000000..620e3719d0 --- /dev/null +++ b/pkg/resources/config/samples/bases/camel_v1_integrationprofile.yaml @@ -0,0 +1,27 @@ +# --------------------------------------------------------------------------- +# 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/v1 +kind: IntegrationProfile +metadata: + name: debug + labels: + app: "camel-k" +spec: + traits: + logging: + level: DEBUG diff --git a/pkg/resources/config/samples/kustomization.yaml b/pkg/resources/config/samples/kustomization.yaml index 85c8ee6a7d..e973532e24 100644 --- a/pkg/resources/config/samples/kustomization.yaml +++ b/pkg/resources/config/samples/kustomization.yaml @@ -22,6 +22,7 @@ # resources: - bases/camel_v1_integrationplatform.yaml +- bases/camel_v1_integrationprofile.yaml - bases/camel_v1_integration.yaml - bases/camel_v1_integrationkit.yaml - bases/camel_v1_camelcatalog.yaml diff --git a/pkg/resources/resources/viewer/user-global-platform-viewer-role-binding.yaml b/pkg/resources/resources/viewer/user-global-platform-viewer-role-binding.yaml index 6d13f8a6b4..3dd6d36294 100644 --- a/pkg/resources/resources/viewer/user-global-platform-viewer-role-binding.yaml +++ b/pkg/resources/resources/viewer/user-global-platform-viewer-role-binding.yaml @@ -17,7 +17,7 @@ # # RoleBinding installed in the operator namespace -# to allow access to integrationplatforms +# to allow access to integrationplatforms and integrationprofiles # apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding diff --git a/pkg/resources/resources/viewer/user-global-platform-viewer-role.yaml b/pkg/resources/resources/viewer/user-global-platform-viewer-role.yaml index d5a1b8e18e..6f7943b9e2 100644 --- a/pkg/resources/resources/viewer/user-global-platform-viewer-role.yaml +++ b/pkg/resources/resources/viewer/user-global-platform-viewer-role.yaml @@ -17,7 +17,7 @@ # # Role installed in the operator namespace -# to allow access to operator installed integrationplatforms +# to allow access to operator installed integrationplatforms and integrationprofiles # apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -30,6 +30,7 @@ rules: - "camel.apache.org" resources: - integrationplatforms + - integrationprofiles verbs: - get - list diff --git a/pkg/resources/resources_test.go b/pkg/resources/resources_test.go index 05d1ed9d57..d6f73d1dac 100644 --- a/pkg/resources/resources_test.go +++ b/pkg/resources/resources_test.go @@ -155,6 +155,7 @@ func TestCRDResources(t *testing.T) { NoErrorAndNotEmptyBytes(t, "/config/crd/bases/camel.apache.org_camelcatalogs.yaml", Resource) NoErrorAndNotEmptyBytes(t, "/config/crd/bases/camel.apache.org_integrationkits.yaml", Resource) NoErrorAndNotEmptyBytes(t, "/config/crd/bases/camel.apache.org_integrationplatforms.yaml", Resource) + NoErrorAndNotEmptyBytes(t, "/config/crd/bases/camel.apache.org_integrationprofiles.yaml", Resource) NoErrorAndNotEmptyBytes(t, "/config/crd/bases/camel.apache.org_integrations.yaml", Resource) NoErrorAndNotEmptyBytes(t, "/config/crd/bases/camel.apache.org_kamelets.yaml", Resource) NoErrorAndNotEmptyBytes(t, "/config/crd/bases/camel.apache.org_kameletbindings.yaml", Resource) diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go index 2375640778..6f1eba4b9f 100644 --- a/pkg/trait/camel.go +++ b/pkg/trait/camel.go @@ -225,6 +225,9 @@ func determineRuntimeVersion(e *Environment) (string, error) { if e.IntegrationKit != nil && e.IntegrationKit.Status.RuntimeVersion != "" { return e.IntegrationKit.Status.RuntimeVersion, nil } + if e.IntegrationProfile != nil && e.IntegrationProfile.Status.Build.RuntimeVersion != "" { + return e.IntegrationProfile.Status.Build.RuntimeVersion, nil + } if e.Platform != nil && e.Platform.Status.Build.RuntimeVersion != "" { return e.Platform.Status.Build.RuntimeVersion, nil } diff --git a/pkg/trait/container.go b/pkg/trait/container.go index 16f1e72edd..e4384f25a3 100644 --- a/pkg/trait/container.go +++ b/pkg/trait/container.go @@ -146,6 +146,19 @@ func (t *containerTrait) configureImageIntegrationKit(e *Environment) error { if v, ok := e.Integration.Annotations[v1.PlatformSelectorAnnotation]; ok { v1.SetAnnotation(&kit.ObjectMeta, v1.PlatformSelectorAnnotation, v) } + + if v, ok := e.Integration.Annotations[v1.IntegrationProfileAnnotation]; ok { + v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileAnnotation, v) + + if v, ok := e.Integration.Annotations[v1.IntegrationProfileNamespaceAnnotation]; ok { + v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, v) + } else { + // set integration profile namespace to the integration namespace. + // this is because the kit may live in another namespace and needs to resolve the integration profile from the integration namespace. + v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, e.Integration.Namespace) + } + } + operatorID := defaults.OperatorID() if operatorID != "" { kit.SetOperatorID(operatorID) diff --git a/pkg/trait/platform.go b/pkg/trait/platform.go index 3973105018..5b69e69ee5 100644 --- a/pkg/trait/platform.go +++ b/pkg/trait/platform.go @@ -109,7 +109,7 @@ func (t *platformTrait) Apply(e *Environment) error { } func (t *platformTrait) getOrCreatePlatform(e *Environment) (*v1.IntegrationPlatform, error) { - pl, err := platform.GetOrFindForResource(e.Ctx, t.Client, e.Integration, false) + pl, err := platform.GetForResource(e.Ctx, t.Client, e.Integration) if err != nil && apierrors.IsNotFound(err) && pointer.BoolDeref(t.CreateDefault, false) { platformName := e.Integration.Status.Platform if platformName == "" { diff --git a/pkg/trait/quarkus.go b/pkg/trait/quarkus.go index cb8b216f0b..52ca72399d 100644 --- a/pkg/trait/quarkus.go +++ b/pkg/trait/quarkus.go @@ -263,6 +263,18 @@ func (t *quarkusTrait) newIntegrationKit(e *Environment, packageType quarkusPack v1.SetAnnotation(&kit.ObjectMeta, v1.PlatformSelectorAnnotation, v) } + if v, ok := integration.Annotations[v1.IntegrationProfileAnnotation]; ok { + v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileAnnotation, v) + + if v, ok := e.Integration.Annotations[v1.IntegrationProfileNamespaceAnnotation]; ok { + v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, v) + } else { + // set integration profile namespace to the integration namespace. + // this is because the kit may live in another namespace and needs to resolve the integration profile from the integration namespace. + v1.SetAnnotation(&kit.ObjectMeta, v1.IntegrationProfileNamespaceAnnotation, e.Integration.Namespace) + } + } + for k, v := range integration.Annotations { if strings.HasPrefix(k, v1.TraitAnnotationPrefix) { v1.SetAnnotation(&kit.ObjectMeta, k, v) @@ -287,25 +299,45 @@ func (t *quarkusTrait) newIntegrationKit(e *Environment, packageType quarkusPack } func propagateKitTraits(e *Environment) v1.IntegrationKitTraits { - traits := e.Integration.Spec.Traits - kitTraits := v1.IntegrationKitTraits{ + kitTraits := v1.IntegrationKitTraits{} + + if e.Platform != nil { + propagate(fmt.Sprintf("platform %q", e.Platform.Name), e.Platform.Status.Traits, &kitTraits, e) + } + + if e.IntegrationProfile != nil { + propagate(fmt.Sprintf("integration profile %q", e.IntegrationProfile.Name), e.IntegrationProfile.Status.Traits, &kitTraits, e) + } + + propagate(fmt.Sprintf("integration %q", e.Integration.Name), e.Integration.Spec.Traits, &kitTraits, e) + + return kitTraits +} + +func propagate(traitSource string, traits v1.Traits, kitTraits *v1.IntegrationKitTraits, e *Environment) { + ikt := v1.IntegrationKitTraits{ Builder: traits.Builder.DeepCopy(), Camel: traits.Camel.DeepCopy(), Quarkus: traits.Quarkus.DeepCopy(), Registry: traits.Registry.DeepCopy(), } + if err := kitTraits.Merge(ikt); err != nil { + log.Errorf(err, "Unable to propagate traits from %s to the integration kit", traitSource) + } + // propagate addons that influence kits too if len(traits.Addons) > 0 { - kitTraits.Addons = make(map[string]v1.AddonTrait) + if kitTraits.Addons == nil { + kitTraits.Addons = make(map[string]v1.AddonTrait) + } + for id, addon := range traits.Addons { if t := e.Catalog.GetTrait(id); t != nil && t.InfluencesKit() { kitTraits.Addons[id] = *addon.DeepCopy() } } } - - return kitTraits } func (t *quarkusTrait) applyWhenBuildSubmitted(e *Environment) error { diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go index bfbd438524..4ac35aa147 100644 --- a/pkg/trait/trait.go +++ b/pkg/trait/trait.go @@ -117,6 +117,11 @@ func newEnvironment(ctx context.Context, c client.Client, integration *v1.Integr return nil, err } + ipr, err := platform.ApplyIntegrationProfile(ctx, c, pl, obj) + if err != nil { + return nil, err + } + if kit == nil { kit, err = getIntegrationKit(ctx, c, integration) if err != nil { @@ -131,6 +136,7 @@ func newEnvironment(ctx context.Context, c client.Client, integration *v1.Integr env := Environment{ Ctx: ctx, Platform: pl, + IntegrationProfile: ipr, Client: c, IntegrationKit: kit, Integration: integration, @@ -153,6 +159,7 @@ func NewSyntheticEnvironment(ctx context.Context, c client.Client, integration * env := Environment{ Ctx: ctx, Platform: nil, + IntegrationProfile: nil, Client: c, IntegrationKit: kit, Integration: integration, diff --git a/pkg/trait/trait_configure.go b/pkg/trait/trait_configure.go index 12091fb12a..c1c19706dd 100644 --- a/pkg/trait/trait_configure.go +++ b/pkg/trait/trait_configure.go @@ -40,6 +40,11 @@ func (c *Catalog) Configure(env *Environment) error { return err } } + if env.IntegrationProfile != nil { + if err := c.configureTraits(env.IntegrationProfile.Status.Traits); err != nil { + return err + } + } if env.IntegrationKit != nil { if err := c.configureTraits(env.IntegrationKit.Spec.Traits); err != nil { return err diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go index 602e59c723..3693a9ef5f 100644 --- a/pkg/trait/trait_types.go +++ b/pkg/trait/trait_types.go @@ -207,6 +207,8 @@ type Environment struct { Client client.Client // The active Platform Platform *v1.IntegrationPlatform + // The active IntegrationProfile + IntegrationProfile *v1.IntegrationProfile // The current Integration Integration *v1.Integration // The IntegrationKit associated to the Integration diff --git a/pkg/trait/util.go b/pkg/trait/util.go index d8b4d4acd1..19089baac3 100644 --- a/pkg/trait/util.go +++ b/pkg/trait/util.go @@ -349,11 +349,11 @@ func Equals(i1 Options, i2 Options) bool { // IntegrationsHaveSameTraits return if traits are the same. func IntegrationsHaveSameTraits(i1 *v1.Integration, i2 *v1.Integration) (bool, error) { - c1, err := NewStatusTraitsOptionsForIntegration(i1) + c1, err := NewSpecTraitsOptionsForIntegration(i1) if err != nil { return false, err } - c2, err := NewStatusTraitsOptionsForIntegration(i2) + c2, err := NewSpecTraitsOptionsForIntegration(i2) if err != nil { return false, err } @@ -394,7 +394,7 @@ func KameletBindingsHaveSameTraits(i1 *v1alpha1.KameletBinding, i2 *v1alpha1.Kam // The comparison is done for the subset of traits defines on the binding as during the trait processing, // some traits may be added to the Integration i.e. knative configuration in case of sink binding. func IntegrationAndPipeSameTraits(i1 *v1.Integration, i2 *v1.Pipe) (bool, error) { - itOpts, err := NewStatusTraitsOptionsForIntegration(i1) + itOpts, err := NewSpecTraitsOptionsForIntegration(i1) if err != nil { return false, err } @@ -418,7 +418,7 @@ func IntegrationAndPipeSameTraits(i1 *v1.Integration, i2 *v1.Pipe) (bool, error) // some traits may be added to the Integration i.e. knative configuration in case of sink binding. // Deprecated. func IntegrationAndKameletBindingSameTraits(i1 *v1.Integration, i2 *v1alpha1.KameletBinding) (bool, error) { - itOpts, err := NewStatusTraitsOptionsForIntegration(i1) + itOpts, err := NewSpecTraitsOptionsForIntegration(i1) if err != nil { return false, err } @@ -450,8 +450,32 @@ func newTraitsOptions(opts Options, objectMeta *metav1.ObjectMeta) (Options, err return opts, nil } -func NewStatusTraitsOptionsForIntegration(i *v1.Integration) (Options, error) { - m1, err := ToTraitMap(i.Status.Traits) +func NewSpecTraitsOptionsForIntegrationAndPlatform(i *v1.Integration, pl *v1.IntegrationPlatform) (Options, error) { + var options Options + var err error + if pl != nil { + options, err = ToTraitMap(pl.Status.Traits) + if err != nil { + return nil, err + } + } else { + options = Options{} + } + + m1, err := ToTraitMap(i.Spec.Traits) + if err != nil { + return nil, err + } + + for k, v := range m1 { + options[k] = v + } + + return newTraitsOptions(options, &i.ObjectMeta) +} + +func NewSpecTraitsOptionsForIntegration(i *v1.Integration) (Options, error) { + m1, err := ToTraitMap(i.Spec.Traits) if err != nil { return nil, err } @@ -476,68 +500,39 @@ func NewSpecTraitsOptionsForIntegrationKit(i *v1.IntegrationKit) (Options, error return newTraitsOptionsForIntegrationKit(i, i.Spec.Traits) } -func NewTraitsOptionsForIntegrationPlatform(i *v1.IntegrationPlatform) (Options, error) { - m1, err := ToTraitMap(i.Spec.Traits) - if err != nil { - return nil, err - } - - return newTraitsOptions(m1, &i.ObjectMeta) -} - -func NewTraitsOptionsForPipe(i *v1.Pipe) (Options, error) { - if i.Spec.Integration != nil { - m1, err := ToTraitMap(i.Spec.Integration.Traits) - if err != nil { - return nil, err - } +func NewTraitsOptionsForPipe(pipe *v1.Pipe) (Options, error) { + options := Options{} - m2, err := FromAnnotations(&i.ObjectMeta) + if pipe.Spec.Integration != nil { + m1, err := ToTraitMap(pipe.Spec.Integration.Traits) if err != nil { return nil, err } - for k, v := range m2 { - m1[k] = v + for k, v := range m1 { + options[k] = v } - - return m1, nil - } - - m1, err := FromAnnotations(&i.ObjectMeta) - if err != nil { - return nil, err } - return m1, nil + return newTraitsOptions(options, &pipe.ObjectMeta) } // Deprecated. -func NewTraitsOptionsForKameletBinding(i *v1alpha1.KameletBinding) (Options, error) { - if i.Spec.Integration != nil { - m1, err := ToTraitMap(i.Spec.Integration.Traits) - if err != nil { - return nil, err - } +func NewTraitsOptionsForKameletBinding(kb *v1alpha1.KameletBinding) (Options, error) { + options := Options{} - m2, err := FromAnnotations(&i.ObjectMeta) + if kb.Spec.Integration != nil { + m1, err := ToTraitMap(kb.Spec.Integration.Traits) if err != nil { return nil, err } - for k, v := range m2 { - m1[k] = v + for k, v := range m1 { + options[k] = v } - - return m1, nil - } - - m1, err := FromAnnotations(&i.ObjectMeta) - if err != nil { - return nil, err } - return m1, nil + return newTraitsOptions(options, &kb.ObjectMeta) } func FromAnnotations(meta *metav1.ObjectMeta) (Options, error) { diff --git a/pkg/util/digest/digest.go b/pkg/util/digest/digest.go index 5be06aa43d..8e34d097b8 100644 --- a/pkg/util/digest/digest.go +++ b/pkg/util/digest/digest.go @@ -59,6 +59,14 @@ func ComputeForIntegration(integration *v1.Integration, configmaps []*corev1.Con return "", err } + // Integration profile is relevant + if _, err := hash.Write([]byte(v1.GetIntegrationProfileAnnotation(integration))); err != nil { + return "", err + } + if _, err := hash.Write([]byte(v1.GetIntegrationProfileNamespaceAnnotation(integration))); err != nil { + return "", err + } + // Integration Kit is relevant if integration.Spec.IntegrationKit != nil { if _, err := hash.Write([]byte(fmt.Sprintf("%s/%s", integration.Spec.IntegrationKit.Namespace, integration.Spec.IntegrationKit.Name))); err != nil { diff --git a/pkg/util/kubernetes/client.go b/pkg/util/kubernetes/client.go index ef2ffc0b7b..d47773b894 100644 --- a/pkg/util/kubernetes/client.go +++ b/pkg/util/kubernetes/client.go @@ -44,6 +44,17 @@ func GetIntegrationPlatform(context context.Context, client ctrl.Reader, name st return &platform, nil } +func GetIntegrationProfile(context context.Context, client ctrl.Reader, name string, namespace string) (*v1.IntegrationProfile, error) { + integrationProfile := v1.NewIntegrationProfile(namespace, name) + log.Debugf("Integration Profile [name: %s], [namespace: %s], [objectkey: %s]", name, namespace, ctrl.ObjectKeyFromObject(&integrationProfile)) + if err := client.Get(context, ctrl.ObjectKeyFromObject(&integrationProfile), &integrationProfile); err != nil { + log.Debugf("Integration profile Error: %v", err) + return nil, err + } + + return &integrationProfile, nil +} + func GetCamelCatalog(context context.Context, client ctrl.Reader, name string, namespace string) (*v1.CamelCatalog, error) { catalog := v1.NewCamelCatalog(namespace, name) log.Debugf("Camel Catalog [name: %s], [namespace: %s], [objectkey: %s]", name, namespace, ctrl.ObjectKeyFromObject(&catalog)) diff --git a/pkg/util/log/log.go b/pkg/util/log/log.go index 4c47aa6109..a57e722c48 100644 --- a/pkg/util/log/log.go +++ b/pkg/util/log/log.go @@ -135,6 +135,16 @@ func (l Logger) ForIntegrationPlatform(target *v1.IntegrationPlatform) Logger { ) } +// ForIntegrationProfile --. +func (l Logger) ForIntegrationProfile(target *v1.IntegrationProfile) Logger { + return l.WithValues( + "api-version", target.APIVersion, + "kind", target.Kind, + "ns", target.Namespace, + "name", target.Name, + ) +} + // ForKamelet --. func (l Logger) ForKamelet(target *v1.Kamelet) Logger { return l.WithValues( diff --git a/script/gen_crd.sh b/script/gen_crd.sh index 4c26c28a08..58331304ec 100755 --- a/script/gen_crd.sh +++ b/script/gen_crd.sh @@ -67,6 +67,7 @@ deploy_crd camel-catalog camelcatalogs deploy_crd integration integrations deploy_crd integration-kit integrationkits deploy_crd integration-platform integrationplatforms +deploy_crd integration-profile integrationprofiles deploy_crd kamelet kamelets deploy_crd kamelet-binding kameletbindings -deploy_crd pipe pipes \ No newline at end of file +deploy_crd pipe pipes diff --git a/script/prepare-operators.sh b/script/prepare-operators.sh index bfbd1cc4d0..3b9397d6ab 100755 --- a/script/prepare-operators.sh +++ b/script/prepare-operators.sh @@ -38,6 +38,7 @@ cp ./manifests/camel.apache.org_builds.yaml k8s-operatorhub/$1/manifests/builds. cp ./manifests/camel.apache.org_camelcatalogs.yaml k8s-operatorhub/$1/manifests/camelcatalogs.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_integrationkits.yaml k8s-operatorhub/$1/manifests/integrationkits.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_integrationplatforms.yaml k8s-operatorhub/$1/manifests/integrationplatforms.camel.apache.org.crd.yaml +cp ./manifests/camel.apache.org_integrationprofiles.yaml k8s-operatorhub/$1/manifests/integrationprofiles.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_integrations.yaml k8s-operatorhub/$1/manifests/integrations.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_kamelets.yaml k8s-operatorhub/$1/manifests/kamelets.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_kameletbindings.yaml k8s-operatorhub/$1/manifests/kameletbindings.camel.apache.org.crd.yaml @@ -50,6 +51,7 @@ cp ./manifests/camel.apache.org_builds.yaml openshift-ecosystem/$1/manifests/bui cp ./manifests/camel.apache.org_camelcatalogs.yaml openshift-ecosystem/$1/manifests/camelcatalogs.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_integrationkits.yaml openshift-ecosystem/$1/manifests/integrationkits.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_integrationplatforms.yaml openshift-ecosystem/$1/manifests/integrationplatforms.camel.apache.org.crd.yaml +cp ./manifests/camel.apache.org_integrationprofiles.yaml openshift-ecosystem/$1/manifests/integrationprofiles.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_integrations.yaml openshift-ecosystem/$1/manifests/integrations.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_kamelets.yaml openshift-ecosystem/$1/manifests/kamelets.camel.apache.org.crd.yaml cp ./manifests/camel.apache.org_kameletbindings.yaml openshift-ecosystem/$1/manifests/kameletbindings.camel.apache.org.crd.yaml