From 5eddd27a3d5b00b6dbd3cbf95ca736aad1c657a3 Mon Sep 17 00:00:00 2001 From: Pasquale Congiusti Date: Sat, 11 Jan 2025 09:47:11 +0100 Subject: [PATCH] chore(addons): move master into traits Ref #5787 --- addons/addons_test.go | 77 ----- addons/master/client_test.go | 299 ------------------ addons/master/test_support.go | 21 -- addons/master/zz_desc_generated.go | 1 - addons/master/zz_generated_doc.go | 1 - addons/register_master.go | 27 -- .../ROOT/partials/apis/camel-k-crds.adoc | 91 +++++- helm/camel-k/crds/camel-k-crds.yaml | 267 ++++++++++++++-- pkg/apis/camel/v1/common_types.go | 4 +- pkg/apis/camel/v1/trait/master.go | 46 +++ .../camel/v1/trait/zz_generated.deepcopy.go | 46 +++ pkg/apis/camel/v1/zz_generated.deepcopy.go | 10 +- .../applyconfiguration/camel/v1/traits.go | 18 +- ...camel.apache.org_integrationplatforms.yaml | 76 ++++- .../camel.apache.org_integrationprofiles.yaml | 76 ++++- .../bases/camel.apache.org_integrations.yaml | 76 ++++- .../crd/bases/camel.apache.org_pipes.yaml | 39 ++- {addons/master => pkg/trait}/master.go | 53 +--- {addons/master => pkg/trait}/master_test.go | 30 +- pkg/trait/trait_register.go | 1 + 20 files changed, 698 insertions(+), 561 deletions(-) delete mode 100644 addons/addons_test.go delete mode 100644 addons/master/client_test.go delete mode 100644 addons/master/test_support.go delete mode 100644 addons/master/zz_desc_generated.go delete mode 100644 addons/master/zz_generated_doc.go delete mode 100644 addons/register_master.go create mode 100644 pkg/apis/camel/v1/trait/master.go rename {addons/master => pkg/trait}/master.go (71%) rename {addons/master => pkg/trait}/master_test.go (93%) diff --git a/addons/addons_test.go b/addons/addons_test.go deleted file mode 100644 index 9ae5dc165c..0000000000 --- a/addons/addons_test.go +++ /dev/null @@ -1,77 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package addons - -import ( - "encoding/json" - "testing" - - "github.com/apache/camel-k/v2/addons/master" - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" - "github.com/apache/camel-k/v2/pkg/trait" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestTraitConfiguration(t *testing.T) { - env := trait.Environment{ - Integration: &v1.Integration{ - Spec: v1.IntegrationSpec{ - Profile: v1.TraitProfileKubernetes, - Traits: v1.Traits{ - Addons: map[string]v1.AddonTrait{ - "master": toAddonTrait(t, map[string]interface{}{ - "enabled": true, - "resourceName": "test-lock", - "labelKey": "test-label", - "labelValue": "test-value", - }), - "telemetry": toAddonTrait(t, map[string]interface{}{ - "enabled": true, - }), - }, - }, - }, - }, - } - c := trait.NewCatalog(nil) - require.NoError(t, c.Configure(&env)) - - require.NotNil(t, c.GetTrait("master")) - master, ok := c.GetTrait("master").(*master.TestMasterTrait) - require.True(t, ok) - assert.True(t, *master.Enabled) - assert.Equal(t, "test-lock", *master.ResourceName) - assert.Equal(t, "test-label", *master.LabelKey) - assert.Equal(t, "test-value", *master.LabelValue) - -} - -func toAddonTrait(t *testing.T, config map[string]interface{}) v1.AddonTrait { - t.Helper() - - data, err := json.Marshal(config) - require.NoError(t, err) - - var addon v1.AddonTrait - err = json.Unmarshal(data, &addon) - require.NoError(t, err) - - return addon -} diff --git a/addons/master/client_test.go b/addons/master/client_test.go deleted file mode 100644 index 1c2aaef57f..0000000000 --- a/addons/master/client_test.go +++ /dev/null @@ -1,299 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// IMPORTANT: this is a clone of pkg/internal. As the addons will be moved into pkg, we are using this utility here temporarily only! - -package master - -import ( - "context" - "fmt" - "strings" - - "github.com/apache/camel-k/v2/pkg/apis" - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" - "github.com/apache/camel-k/v2/pkg/client" - fakecamelclientset "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned/fake" - camelv1 "github.com/apache/camel-k/v2/pkg/client/camel/clientset/versioned/typed/camel/v1" - "github.com/apache/camel-k/v2/pkg/util" - autoscalingv1 "k8s.io/api/autoscaling/v1" - corev1 "k8s.io/api/core/v1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/discovery" - "k8s.io/client-go/kubernetes" - fakeclientset "k8s.io/client-go/kubernetes/fake" - clientscheme "k8s.io/client-go/kubernetes/scheme" - authorizationv1 "k8s.io/client-go/kubernetes/typed/authorization/v1" - "k8s.io/client-go/rest" - "k8s.io/client-go/scale" - fakescale "k8s.io/client-go/scale/fake" - "k8s.io/client-go/testing" - controller "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/client/fake" - "sigs.k8s.io/controller-runtime/pkg/client/interceptor" -) - -// newFakeClient ---. -func newFakeClient(initObjs ...runtime.Object) (client.Client, error) { - scheme := clientscheme.Scheme - - // Setup Scheme for all resources - if err := apis.AddToScheme(scheme); err != nil { - return nil, err - } - - c := fake. - NewClientBuilder(). - WithScheme(scheme). - WithIndex( - &corev1.Pod{}, - "status.phase", - func(obj controller.Object) []string { - pod, _ := obj.(*corev1.Pod) - return []string{string(pod.Status.Phase)} - }, - ). - WithRuntimeObjects(initObjs...). - WithStatusSubresource(&v1.IntegrationKit{}). - Build() - - camelClientset := fakecamelclientset.NewSimpleClientset(filterObjects(scheme, initObjs, func(gvk schema.GroupVersionKind) bool { - return strings.Contains(gvk.Group, "camel") - })...) - clientset := fakeclientset.NewSimpleClientset(filterObjects(scheme, initObjs, func(gvk schema.GroupVersionKind) bool { - return !strings.Contains(gvk.Group, "camel") && !strings.Contains(gvk.Group, "knative") - })...) - replicasCount := make(map[string]int32) - fakescaleclient := fakescale.FakeScaleClient{} - fakescaleclient.AddReactor("update", "*", func(rawAction testing.Action) (bool, runtime.Object, error) { - //nolint:forcetypeassert - action := rawAction.(testing.UpdateAction) - - //nolint:forcetypeassert - obj := action.GetObject().(*autoscalingv1.Scale) - - replicas := obj.Spec.Replicas - key := fmt.Sprintf("%s:%s:%s/%s", action.GetResource().Group, action.GetResource().Resource, action.GetNamespace(), obj.GetName()) - replicasCount[key] = replicas - return true, &autoscalingv1.Scale{ - ObjectMeta: metav1.ObjectMeta{ - Name: obj.Name, - Namespace: action.GetNamespace(), - }, - Spec: autoscalingv1.ScaleSpec{ - Replicas: replicas, - }, - }, nil - }) - fakescaleclient.AddReactor("get", "*", func(rawAction testing.Action) (bool, runtime.Object, error) { - //nolint:forcetypeassert - action := rawAction.(testing.GetAction) - - key := fmt.Sprintf("%s:%s:%s/%s", action.GetResource().Group, action.GetResource().Resource, action.GetNamespace(), action.GetName()) - obj := &autoscalingv1.Scale{ - ObjectMeta: metav1.ObjectMeta{ - Name: action.GetName(), - Namespace: action.GetNamespace(), - }, - Spec: autoscalingv1.ScaleSpec{ - Replicas: replicasCount[key], - }, - } - return true, obj, nil - }) - - return &FakeClient{ - Client: c, - Interface: clientset, - camel: camelClientset, - scales: &fakescaleclient, - enabledKnativeServing: true, - enabledKnativeEventing: true, - }, nil -} - -func filterObjects(scheme *runtime.Scheme, input []runtime.Object, filter func(gvk schema.GroupVersionKind) bool) []runtime.Object { - var res []runtime.Object - for _, obj := range input { - kinds, _, _ := scheme.ObjectKinds(obj) - for _, k := range kinds { - if filter(k) { - res = append(res, obj) - break - } - } - } - return res -} - -// FakeClient ---. -type FakeClient struct { - controller.Client - kubernetes.Interface - camel *fakecamelclientset.Clientset - scales *fakescale.FakeScaleClient - disabledGroups []string - enabledOpenshift bool - enabledKnativeServing bool - enabledKnativeEventing bool -} - -func (c *FakeClient) Intercept(intercept *interceptor.Funcs) { - //nolint:forcetypeassert - cw := c.Client.(controller.WithWatch) - c.Client = interceptor.NewClient(cw, *intercept) -} - -func (c *FakeClient) AddReactor(verb, resource string, reaction testing.ReactionFunc) { - c.camel.AddReactor(verb, resource, reaction) -} - -func (c *FakeClient) CamelV1() camelv1.CamelV1Interface { - return c.camel.CamelV1() -} - -// GetScheme ---. -func (c *FakeClient) GetScheme() *runtime.Scheme { - return clientscheme.Scheme -} - -func (c *FakeClient) GetConfig() *rest.Config { - return &rest.Config{} -} - -func (c *FakeClient) GetCurrentNamespace(kubeConfig string) (string, error) { - return "", nil -} - -// Patch mimicks patch for server-side apply and simply creates the obj. -func (c *FakeClient) Patch(ctx context.Context, obj controller.Object, patch controller.Patch, opts ...controller.PatchOption) error { - if err := c.Create(ctx, obj); err != nil { - // Create fails if object already exists. Try to update it. - return c.Update(ctx, obj) - } - return nil -} - -func (c *FakeClient) DisableAPIGroupDiscovery(group string) { - c.disabledGroups = append(c.disabledGroups, group) -} - -func (c *FakeClient) EnableOpenshiftDiscovery() { - c.enabledOpenshift = true -} - -func (c *FakeClient) DisableKnativeServing() { - c.enabledKnativeServing = false -} - -func (c *FakeClient) DisableKnativeEventing() { - c.enabledKnativeEventing = false -} - -func (c *FakeClient) AuthorizationV1() authorizationv1.AuthorizationV1Interface { - return &FakeAuthorization{ - AuthorizationV1Interface: c.Interface.AuthorizationV1(), - disabledGroups: c.disabledGroups, - enabledOpenshift: c.enabledOpenshift, - } -} - -func (c *FakeClient) Discovery() discovery.DiscoveryInterface { - return &FakeDiscovery{ - DiscoveryInterface: c.Interface.Discovery(), - disabledGroups: c.disabledGroups, - enabledOpenshift: c.enabledOpenshift, - enabledKnativeServing: c.enabledKnativeServing, - enabledKnativeEventing: c.enabledKnativeEventing, - } -} - -func (c *FakeClient) ServerOrClientSideApplier() client.ServerOrClientSideApplier { - return client.ServerOrClientSideApplier{ - Client: c, - } -} - -func (c *FakeClient) ScalesClient() (scale.ScalesGetter, error) { - return c.scales, nil -} - -type FakeAuthorization struct { - authorizationv1.AuthorizationV1Interface - disabledGroups []string - enabledOpenshift bool -} - -func (f *FakeAuthorization) SelfSubjectRulesReviews() authorizationv1.SelfSubjectRulesReviewInterface { - return f.AuthorizationV1Interface.SelfSubjectRulesReviews() -} - -type FakeDiscovery struct { - discovery.DiscoveryInterface - disabledGroups []string - enabledOpenshift bool - enabledKnativeServing bool - enabledKnativeEventing bool -} - -func (f *FakeDiscovery) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) { - // Normalize the fake discovery to behave like the real implementation when checking for openshift - if groupVersion == "image.openshift.io/v1" { - if f.enabledOpenshift { - return &metav1.APIResourceList{ - GroupVersion: "image.openshift.io/v1", - }, nil - } else { - return nil, k8serrors.NewNotFound(schema.GroupResource{ - Group: "image.openshift.io", - }, "") - } - } - - // used to verify if Knative Serving is installed - if f.enabledKnativeServing { - if groupVersion == "serving.knative.dev/v1" && !util.StringSliceExists(f.disabledGroups, groupVersion) { - return &metav1.APIResourceList{ - GroupVersion: "serving.knative.dev/v1", - }, nil - } - } - - // used to verify if Knative Eventing is installed - if f.enabledKnativeEventing { - if groupVersion == "eventing.knative.dev/v1" && !util.StringSliceExists(f.disabledGroups, groupVersion) { - return &metav1.APIResourceList{ - GroupVersion: "eventing.knative.dev/v1", - }, nil - } - if groupVersion == "messaging.knative.dev/v1" && !util.StringSliceExists(f.disabledGroups, groupVersion) { - return &metav1.APIResourceList{ - GroupVersion: "messaging.knative.dev/v1", - }, nil - } - if groupVersion == "messaging.knative.dev/v1beta1" && !util.StringSliceExists(f.disabledGroups, groupVersion) { - return &metav1.APIResourceList{ - GroupVersion: "messaging.knative.dev/v1beta1", - }, nil - } - } - - return f.DiscoveryInterface.ServerResourcesForGroupVersion(groupVersion) -} diff --git a/addons/master/test_support.go b/addons/master/test_support.go deleted file mode 100644 index ec6b7bf3bc..0000000000 --- a/addons/master/test_support.go +++ /dev/null @@ -1,21 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package master - -// Expose masterTrait type for testing. -type TestMasterTrait = masterTrait diff --git a/addons/master/zz_desc_generated.go b/addons/master/zz_desc_generated.go deleted file mode 100644 index 57d5fb2964..0000000000 --- a/addons/master/zz_desc_generated.go +++ /dev/null @@ -1 +0,0 @@ -package master diff --git a/addons/master/zz_generated_doc.go b/addons/master/zz_generated_doc.go deleted file mode 100644 index 57d5fb2964..0000000000 --- a/addons/master/zz_generated_doc.go +++ /dev/null @@ -1 +0,0 @@ -package master diff --git a/addons/register_master.go b/addons/register_master.go deleted file mode 100644 index 22d4516629..0000000000 --- a/addons/register_master.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Licensed to the Apache Software Foundation (ASF) under one or more -contributor license agreements. See the NOTICE file distributed with -this work for additional information regarding copyright ownership. -The ASF licenses this file to You under the Apache License, Version 2.0 -(the "License"); you may not use this file except in compliance with -the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package addons - -import ( - "github.com/apache/camel-k/v2/addons/master" - "github.com/apache/camel-k/v2/pkg/trait" -) - -func init() { - trait.AddToTraits(master.NewMasterTrait) -} diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc index 8cb076f6d0..46be4a0bec 100644 --- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc +++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc @@ -5976,6 +5976,13 @@ The configuration of Knative Service trait The configuration of Logging trait +|`master` + +*xref:#_camel_apache_org_v1_trait_MasterTrait[MasterTrait]* +| + + +The configuration of Master trait + |`mount` + *xref:#_camel_apache_org_v1_trait_MountTrait[MountTrait]* | @@ -6101,13 +6108,6 @@ The extension point with addon traits | -Deprecated: for backward compatibility. - -|`master` + -*xref:#_camel_apache_org_v1_TraitSpec[TraitSpec]* -| - - Deprecated: for backward compatibility. |`strimzi` + @@ -7967,6 +7967,82 @@ bool Enable "pretty printing" of the JSON logs +|=== + +[#_camel_apache_org_v1_trait_MasterTrait] +=== MasterTrait + +*Appears on:* + +* <<#_camel_apache_org_v1_Traits, Traits>> + +The Master trait allows to configure the integration to automatically leverage Kubernetes resources for doing +leader election and starting *master* routes only on certain instances. + +It's activated automatically when using the master endpoint in a route, e.g. `from("master:lockname:telegram:bots")...`. + +NOTE: this trait adds special permissions to the integration service account in order to read/write configmaps and read pods. +It's recommended to use a different service account than "default" when running the integration. + + +[cols="2,2a",options="header"] +|=== +|Field +|Description + +|`Trait` + +*xref:#_camel_apache_org_v1_trait_Trait[Trait]* +|(Members of `Trait` are embedded into this type.) + + + + +|`auto` + +bool +| + + +Enables automatic configuration of the trait. + +|`includeDelegateDependencies` + +bool +| + + +When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. +E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. +It's enabled by default. + +|`resourceName` + +string +| + + +Name of the configmap that will be used to store the lock. Defaults to "-lock". +Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + +|`resourceType` + +string +| + + +Type of Kubernetes resource to use for locking ("ConfigMap" or "Lease"). Defaults to "Lease". + +|`labelKey` + +string +| + + +Label that will be used to identify all pods contending the lock. Defaults to "camel.apache.org/integration". + +|`labelValue` + +string +| + + +Label value that will be used to identify all pods contending the lock. Defaults to the integration name. + + |=== [#_camel_apache_org_v1_trait_MountTrait] @@ -8961,6 +9037,7 @@ The list of taints to tolerate, in the form `Key[=Value]:Effect[:Seconds]` * <<#_camel_apache_org_v1_trait_KnativeServiceTrait, KnativeServiceTrait>> * <<#_camel_apache_org_v1_trait_KnativeTrait, KnativeTrait>> * <<#_camel_apache_org_v1_trait_LoggingTrait, LoggingTrait>> +* <<#_camel_apache_org_v1_trait_MasterTrait, MasterTrait>> * <<#_camel_apache_org_v1_trait_OwnerTrait, OwnerTrait>> * <<#_camel_apache_org_v1_trait_PDBTrait, PDBTrait>> * <<#_camel_apache_org_v1_trait_PodTrait, PodTrait>> diff --git a/helm/camel-k/crds/camel-k-crds.yaml b/helm/camel-k/crds/camel-k-crds.yaml index 42a7f1da5b..99512a2248 100644 --- a/helm/camel-k/crds/camel-k-crds.yaml +++ b/helm/camel-k/crds/camel-k-crds.yaml @@ -4899,14 +4899,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -7095,14 +7125,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -9194,14 +9254,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -11269,14 +11359,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -19725,14 +19845,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -21727,14 +21877,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -31561,14 +31741,45 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. + All traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify + all pods contending the lock. Defaults to the integration + name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go index d181b1e922..7fdc61d100 100644 --- a/pkg/apis/camel/v1/common_types.go +++ b/pkg/apis/camel/v1/common_types.go @@ -220,6 +220,8 @@ type Traits struct { KnativeService *trait.KnativeServiceTrait `property:"knative-service" json:"knative-service,omitempty"` // The configuration of Logging trait Logging *trait.LoggingTrait `property:"logging" json:"logging,omitempty"` + // The configuration of Master trait + Master *trait.MasterTrait `property:"master" json:"master,omitempty"` // The configuration of Mount trait Mount *trait.MountTrait `property:"mount" json:"mount,omitempty"` // The configuration of OpenAPI trait @@ -260,8 +262,6 @@ type Traits struct { // Deprecated: for backward compatibility. Keda *TraitSpec `property:"keda" json:"keda,omitempty"` // Deprecated: for backward compatibility. - Master *TraitSpec `property:"master" json:"master,omitempty"` - // Deprecated: for backward compatibility. Strimzi *TraitSpec `property:"strimzi" json:"strimzi,omitempty"` // Deprecated: for backward compatibility. ThreeScale *TraitSpec `property:"3scale" json:"3scale,omitempty"` diff --git a/pkg/apis/camel/v1/trait/master.go b/pkg/apis/camel/v1/trait/master.go new file mode 100644 index 0000000000..a396a084f2 --- /dev/null +++ b/pkg/apis/camel/v1/trait/master.go @@ -0,0 +1,46 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package trait + +// The Master trait allows to configure the integration to automatically leverage Kubernetes resources for doing +// leader election and starting *master* routes only on certain instances. +// +// It's activated automatically when using the master endpoint in a route, e.g. `from("master:lockname:telegram:bots")...`. +// +// NOTE: this trait adds special permissions to the integration service account in order to read/write configmaps and read pods. +// It's recommended to use a different service account than "default" when running the integration. +// +// +camel-k:trait=master. +type MasterTrait struct { + Trait `property:",squash" json:",inline"` + // Enables automatic configuration of the trait. + Auto *bool `property:"auto" json:"auto,omitempty"` + // When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + // E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + // It's enabled by default. + IncludeDelegateDependencies *bool `property:"include-delegate-dependencies" json:"includeDelegateDependencies,omitempty"` + // Name of the configmap that will be used to store the lock. Defaults to "-lock". + // Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + ResourceName *string `property:"resource-name" json:"resourceName,omitempty"` + // Type of Kubernetes resource to use for locking ("ConfigMap" or "Lease"). Defaults to "Lease". + ResourceType *string `property:"resource-type" json:"resourceType,omitempty"` + // Label that will be used to identify all pods contending the lock. Defaults to "camel.apache.org/integration". + LabelKey *string `property:"label-key" json:"labelKey,omitempty"` + // Label value that will be used to identify all pods contending the lock. Defaults to the integration name. + LabelValue *string `property:"label-value" json:"labelValue,omitempty"` +} diff --git a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go index 23790d11e5..d173bd22eb 100644 --- a/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1/trait/zz_generated.deepcopy.go @@ -773,6 +773,52 @@ func (in *LoggingTrait) DeepCopy() *LoggingTrait { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MasterTrait) DeepCopyInto(out *MasterTrait) { + *out = *in + in.Trait.DeepCopyInto(&out.Trait) + if in.Auto != nil { + in, out := &in.Auto, &out.Auto + *out = new(bool) + **out = **in + } + if in.IncludeDelegateDependencies != nil { + in, out := &in.IncludeDelegateDependencies, &out.IncludeDelegateDependencies + *out = new(bool) + **out = **in + } + if in.ResourceName != nil { + in, out := &in.ResourceName, &out.ResourceName + *out = new(string) + **out = **in + } + if in.ResourceType != nil { + in, out := &in.ResourceType, &out.ResourceType + *out = new(string) + **out = **in + } + if in.LabelKey != nil { + in, out := &in.LabelKey, &out.LabelKey + *out = new(string) + **out = **in + } + if in.LabelValue != nil { + in, out := &in.LabelValue, &out.LabelValue + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MasterTrait. +func (in *MasterTrait) DeepCopy() *MasterTrait { + if in == nil { + return nil + } + out := new(MasterTrait) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MountTrait) DeepCopyInto(out *MountTrait) { *out = *in diff --git a/pkg/apis/camel/v1/zz_generated.deepcopy.go b/pkg/apis/camel/v1/zz_generated.deepcopy.go index a4362f7409..134d4ac2ea 100644 --- a/pkg/apis/camel/v1/zz_generated.deepcopy.go +++ b/pkg/apis/camel/v1/zz_generated.deepcopy.go @@ -3238,6 +3238,11 @@ func (in *Traits) DeepCopyInto(out *Traits) { *out = new(trait.LoggingTrait) (*in).DeepCopyInto(*out) } + if in.Master != nil { + in, out := &in.Master, &out.Master + *out = new(trait.MasterTrait) + (*in).DeepCopyInto(*out) + } if in.Mount != nil { in, out := &in.Mount, &out.Mount *out = new(trait.MountTrait) @@ -3330,11 +3335,6 @@ func (in *Traits) DeepCopyInto(out *Traits) { *out = new(TraitSpec) (*in).DeepCopyInto(*out) } - if in.Master != nil { - in, out := &in.Master, &out.Master - *out = new(TraitSpec) - (*in).DeepCopyInto(*out) - } if in.Strimzi != nil { in, out := &in.Strimzi, &out.Strimzi *out = new(TraitSpec) diff --git a/pkg/client/camel/applyconfiguration/camel/v1/traits.go b/pkg/client/camel/applyconfiguration/camel/v1/traits.go index f6dea6970e..7271acbcee 100644 --- a/pkg/client/camel/applyconfiguration/camel/v1/traits.go +++ b/pkg/client/camel/applyconfiguration/camel/v1/traits.go @@ -46,6 +46,7 @@ type TraitsApplyConfiguration struct { Knative *trait.KnativeTrait `json:"knative,omitempty"` KnativeService *trait.KnativeServiceTrait `json:"knative-service,omitempty"` Logging *trait.LoggingTrait `json:"logging,omitempty"` + Master *trait.MasterTrait `json:"master,omitempty"` Mount *trait.MountTrait `json:"mount,omitempty"` OpenAPI *trait.OpenAPITrait `json:"openapi,omitempty"` Owner *trait.OwnerTrait `json:"owner,omitempty"` @@ -64,7 +65,6 @@ type TraitsApplyConfiguration struct { Toleration *trait.TolerationTrait `json:"toleration,omitempty"` Addons map[string]AddonTraitApplyConfiguration `json:"addons,omitempty"` Keda *TraitSpecApplyConfiguration `json:"keda,omitempty"` - Master *TraitSpecApplyConfiguration `json:"master,omitempty"` Strimzi *TraitSpecApplyConfiguration `json:"strimzi,omitempty"` ThreeScale *TraitSpecApplyConfiguration `json:"3scale,omitempty"` Tracing *TraitSpecApplyConfiguration `json:"tracing,omitempty"` @@ -236,6 +236,14 @@ func (b *TraitsApplyConfiguration) WithLogging(value trait.LoggingTrait) *Traits return b } +// WithMaster sets the Master 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 Master field is set to the value of the last call. +func (b *TraitsApplyConfiguration) WithMaster(value trait.MasterTrait) *TraitsApplyConfiguration { + b.Master = &value + return b +} + // WithMount sets the Mount 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 Mount field is set to the value of the last call. @@ -386,14 +394,6 @@ func (b *TraitsApplyConfiguration) WithKeda(value *TraitSpecApplyConfiguration) return b } -// WithMaster sets the Master 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 Master field is set to the value of the last call. -func (b *TraitsApplyConfiguration) WithMaster(value *TraitSpecApplyConfiguration) *TraitsApplyConfiguration { - b.Master = value - return b -} - // WithStrimzi sets the Strimzi 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 Strimzi field is set to the value of the last call. diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml index a5c62d97a4..c0aba0d23f 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml @@ -1662,14 +1662,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -3858,14 +3888,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml index 84efe52308..26f12b2991 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml @@ -1531,14 +1531,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -3606,14 +3636,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml index 5baf4779a2..51ffeb87f4 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml @@ -7891,14 +7891,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait @@ -9893,14 +9923,44 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. All + traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify all + pods contending the lock. Defaults to the integration name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml index e71202e95d..fb0618682d 100644 --- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml +++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml @@ -7957,14 +7957,45 @@ spec: type: string type: object master: - description: 'Deprecated: for backward compatibility.' + description: The configuration of Master trait properties: + auto: + description: Enables automatic configuration of the trait. + type: boolean configuration: - description: TraitConfiguration parameters configuration + description: |- + Legacy trait configuration parameters. + Deprecated: for backward compatibility. type: object x-kubernetes-preserve-unknown-fields: true - required: - - configuration + enabled: + description: Can be used to enable or disable a trait. + All traits share this common property. + type: boolean + includeDelegateDependencies: + description: |- + When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. + E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. + It's enabled by default. + type: boolean + labelKey: + description: Label that will be used to identify all pods + contending the lock. Defaults to "camel.apache.org/integration". + type: string + labelValue: + description: Label value that will be used to identify + all pods contending the lock. Defaults to the integration + name. + type: string + resourceName: + description: |- + Name of the configmap that will be used to store the lock. Defaults to "-lock". + Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". + type: string + resourceType: + description: Type of Kubernetes resource to use for locking + ("ConfigMap" or "Lease"). Defaults to "Lease". + type: string type: object mount: description: The configuration of Mount trait diff --git a/addons/master/master.go b/pkg/trait/master.go similarity index 71% rename from addons/master/master.go rename to pkg/trait/master.go index 42fc9d6453..d7aa9c1e17 100644 --- a/addons/master/master.go +++ b/pkg/trait/master.go @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -package master +package trait import ( "fmt" @@ -29,50 +29,21 @@ import ( "github.com/apache/camel-k/v2/pkg/client" "github.com/apache/camel-k/v2/pkg/metadata" "github.com/apache/camel-k/v2/pkg/resources" - "github.com/apache/camel-k/v2/pkg/trait" "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/uri" ) -// The Master trait allows to configure the integration to automatically leverage Kubernetes resources for doing -// leader election and starting *master* routes only on certain instances. -// -// It's activated automatically when using the master endpoint in a route, e.g. `from("master:lockname:telegram:bots")...`. -// -// NOTE: this trait adds special permissions to the integration service account in order to read/write configmaps and read pods. -// It's recommended to use a different service account than "default" when running the integration. -// -// +camel-k:trait=master. -type Trait struct { - traitv1.Trait `property:",squash" json:",inline"` - // Enables automatic configuration of the trait. - Auto *bool `property:"auto" json:"auto,omitempty"` - // When this flag is active, the operator analyzes the source code to add dependencies required by delegate endpoints. - // E.g. when using `master:lockname:timer`, then `camel:timer` is automatically added to the set of dependencies. - // It's enabled by default. - IncludeDelegateDependencies *bool `property:"include-delegate-dependencies" json:"includeDelegateDependencies,omitempty"` - // Name of the configmap that will be used to store the lock. Defaults to "-lock". - // Name of the configmap/lease resource that will be used to store the lock. Defaults to "-lock". - ResourceName *string `property:"resource-name" json:"resourceName,omitempty"` - // Type of Kubernetes resource to use for locking ("ConfigMap" or "Lease"). Defaults to "Lease". - ResourceType *string `property:"resource-type" json:"resourceType,omitempty"` - // Label that will be used to identify all pods contending the lock. Defaults to "camel.apache.org/integration". - LabelKey *string `property:"label-key" json:"labelKey,omitempty"` - // Label value that will be used to identify all pods contending the lock. Defaults to the integration name. - LabelValue *string `property:"label-value" json:"labelValue,omitempty"` -} - type masterTrait struct { - trait.BaseTrait - Trait `property:",squash"` + BaseTrait + traitv1.MasterTrait `property:",squash"` delegateDependencies []string } // NewMasterTrait --. -func NewMasterTrait() trait.Trait { +func NewMasterTrait() Trait { return &masterTrait{ - BaseTrait: trait.NewBaseTrait("master", trait.TraitOrderBeforeControllerCreation), + BaseTrait: NewBaseTrait("master", TraitOrderBeforeControllerCreation), } } @@ -81,12 +52,12 @@ const ( leaseResourceType = "Lease" ) -func (t *masterTrait) Configure(e *trait.Environment) (bool, *trait.TraitCondition, error) { +func (t *masterTrait) Configure(e *Environment) (bool, *TraitCondition, error) { if e.Integration == nil { return false, nil, nil } if !ptr.Deref(t.Enabled, true) { - return false, trait.NewIntegrationConditionUserDisabled(masterComponent), nil + return false, NewIntegrationConditionUserDisabled(masterComponent), nil } if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization, v1.IntegrationPhaseBuildingKit) && !e.IntegrationInRunningPhases() { return false, nil, nil @@ -130,7 +101,7 @@ func (t *masterTrait) Configure(e *trait.Environment) (bool, *trait.TraitConditi return enabled, nil, nil } -func (t *masterTrait) Apply(e *trait.Environment) error { +func (t *masterTrait) Apply(e *Environment) error { if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) { util.StringSliceUniqueAdd(&e.Integration.Status.Capabilities, v1.CapabilityMaster) // Master sub endpoints need to be added to the list of dependencies @@ -157,7 +128,7 @@ func (t *masterTrait) Apply(e *trait.Environment) error { } // Deprecated: to be removed in future release in favor of func setCatalogConfiguration(). -func (t *masterTrait) setCustomizerConfiguration(e *trait.Environment) { +func (t *masterTrait) setCustomizerConfiguration(e *Environment) { e.Integration.Status.Configuration = append(e.Integration.Status.Configuration, v1.ConfigurationSpec{Type: "property", Value: "customizer.master.enabled=true"}, ) @@ -175,7 +146,7 @@ func (t *masterTrait) setCustomizerConfiguration(e *trait.Environment) { ) } -func (t *masterTrait) setCatalogConfiguration(e *trait.Environment) { +func (t *masterTrait) setCatalogConfiguration(e *Environment) { if e.ApplicationProperties == nil { e.ApplicationProperties = make(map[string]string) } @@ -185,7 +156,7 @@ func (t *masterTrait) setCatalogConfiguration(e *trait.Environment) { e.ApplicationProperties["camel.k.master.labelValue"] = *t.LabelValue for _, cp := range e.CamelCatalog.Runtime.Capabilities["master"].RuntimeProperties { - e.ApplicationProperties[trait.CapabilityPropertyKey(cp.Key, e.ApplicationProperties)] = cp.Value + e.ApplicationProperties[CapabilityPropertyKey(cp.Key, e.ApplicationProperties)] = cp.Value } } @@ -205,7 +176,7 @@ func (t *masterTrait) getLabelKey() string { return *t.LabelKey } -func findAdditionalDependencies(e *trait.Environment, meta metadata.IntegrationMetadata) []string { +func findAdditionalDependencies(e *Environment, meta metadata.IntegrationMetadata) []string { var dependencies []string for _, endpoint := range meta.FromURIs { if uri.GetComponent(endpoint) == masterComponent { diff --git a/addons/master/master_test.go b/pkg/trait/master_test.go similarity index 93% rename from addons/master/master_test.go rename to pkg/trait/master_test.go index cce4c38f9b..9a96372721 100644 --- a/addons/master/master_test.go +++ b/pkg/trait/master_test.go @@ -15,14 +15,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -package master +package trait import ( "testing" v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait" - "github.com/apache/camel-k/v2/pkg/trait" + "github.com/apache/camel-k/v2/pkg/internal" "github.com/apache/camel-k/v2/pkg/util/camel" "github.com/apache/camel-k/v2/pkg/util/kubernetes" "github.com/stretchr/testify/assert" @@ -36,11 +36,11 @@ func TestMasterOn(t *testing.T) { catalog, err := camel.DefaultCatalog() require.NoError(t, err) - client, err := newFakeClient() + client, err := internal.NewFakeClient() require.NoError(t, err) - traitCatalog := trait.NewCatalog(nil) + traitCatalog := NewCatalog(nil) - environment := trait.Environment{ + environment := Environment{ CamelCatalog: catalog, Catalog: traitCatalog, Client: client, @@ -81,7 +81,7 @@ func TestMasterOn(t *testing.T) { }, }, EnvVars: make([]corev1.EnvVar, 0), - ExecutedTraits: make([]trait.Trait, 0), + ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } environment.Platform.ResyncStatusFullConfig() @@ -127,11 +127,11 @@ func TestMasterOff(t *testing.T) { catalog, err := camel.DefaultCatalog() require.NoError(t, err) - client, err := newFakeClient() + client, err := internal.NewFakeClient() require.NoError(t, err) - traitCatalog := trait.NewCatalog(nil) + traitCatalog := NewCatalog(nil) - environment := trait.Environment{ + environment := Environment{ CamelCatalog: catalog, Catalog: traitCatalog, Client: client, @@ -172,7 +172,7 @@ func TestMasterOff(t *testing.T) { }, }, EnvVars: make([]corev1.EnvVar, 0), - ExecutedTraits: make([]trait.Trait, 0), + ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } environment.Platform.ResyncStatusFullConfig() @@ -190,11 +190,11 @@ func TestMasterAuto(t *testing.T) { catalog, err := camel.DefaultCatalog() require.NoError(t, err) - client, err := newFakeClient() + client, err := internal.NewFakeClient() require.NoError(t, err) - traitCatalog := trait.NewCatalog(nil) + traitCatalog := NewCatalog(nil) - environment := trait.Environment{ + environment := Environment{ CamelCatalog: catalog, Catalog: traitCatalog, Client: client, @@ -234,7 +234,7 @@ func TestMasterAuto(t *testing.T) { }, }, EnvVars: make([]corev1.EnvVar, 0), - ExecutedTraits: make([]trait.Trait, 0), + ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } environment.Platform.ResyncStatusFullConfig() @@ -251,7 +251,7 @@ func TestMasterAuto(t *testing.T) { require.NoError(t, err) expectedTrait := &masterTrait{ - Trait: Trait{ + MasterTrait: traitv1.MasterTrait{ Trait: traitv1.Trait{ Enabled: ptr.To(true), }, diff --git a/pkg/trait/trait_register.go b/pkg/trait/trait_register.go index 032470f349..6d543a88bd 100644 --- a/pkg/trait/trait_register.go +++ b/pkg/trait/trait_register.go @@ -41,6 +41,7 @@ func init() { AddToTraits(newKnativeTrait) AddToTraits(newKnativeServiceTrait) AddToTraits(newLoggingTraitTrait) + AddToTraits(NewMasterTrait) AddToTraits(newMountTrait) AddToTraits(newOpenAPITrait) AddToTraits(newOwnerTrait)