This is an automated email from the ASF dual-hosted git repository. nferraro pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 05fb571f3e6fdbb36fb70581085b00327f80e35d Author: nicolaferraro <ni.ferr...@gmail.com> AuthorDate: Tue Oct 12 17:29:03 2021 +0200 Fix #2687: allow multiple secondary platforms on the same namespace --- pkg/apis/camel/v1/common_types.go | 5 ++-- pkg/controller/integrationplatform/create.go | 3 ++- pkg/controller/integrationplatform/initialize.go | 10 +++++--- pkg/platform/platform.go | 32 +++++++++++++++++++++--- 4 files changed, 41 insertions(+), 9 deletions(-) diff --git a/pkg/apis/camel/v1/common_types.go b/pkg/apis/camel/v1/common_types.go index 78aa968..649ce6e 100644 --- a/pkg/apis/camel/v1/common_types.go +++ b/pkg/apis/camel/v1/common_types.go @@ -23,8 +23,9 @@ import ( ) const ( - TraitAnnotationPrefix = "trait.camel.apache.org/" - OperatorIDLabel = "camel.apache.org/operator.id" + TraitAnnotationPrefix = "trait.camel.apache.org/" + OperatorIDLabel = "camel.apache.org/operator.id" + SecondaryPlatformLabel = "camel.apache.org/secondary.platform" ) // BuildStrategy specifies how the Build should be executed diff --git a/pkg/controller/integrationplatform/create.go b/pkg/controller/integrationplatform/create.go index 6835ee5..2b4a071 100644 --- a/pkg/controller/integrationplatform/create.go +++ b/pkg/controller/integrationplatform/create.go @@ -20,6 +20,7 @@ package integrationplatform import ( "context" + platformutil "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/resources" "github.com/apache/camel-k/pkg/util/defaults" @@ -53,7 +54,7 @@ func (action *createAction) Handle(ctx context.Context, platform *v1.Integration } } - if defaults.InstallDefaultKamelets() { + if !platformutil.IsSecondary(platform) && 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 ccedcb5..eea1a50 100644 --- a/pkg/controller/integrationplatform/initialize.go +++ b/pkg/controller/integrationplatform/initialize.go @@ -49,7 +49,7 @@ func (action *initializeAction) CanHandle(platform *v1.IntegrationPlatform) bool } func (action *initializeAction) Handle(ctx context.Context, platform *v1.IntegrationPlatform) (*v1.IntegrationPlatform, error) { - duplicate, err := action.isDuplicate(ctx, platform) + duplicate, err := action.isPrimaryDuplicate(ctx, platform) if err != nil { return nil, err } @@ -96,8 +96,12 @@ func (action *initializeAction) Handle(ctx context.Context, platform *v1.Integra return platform, nil } -func (action *initializeAction) isDuplicate(ctx context.Context, thisPlatform *v1.IntegrationPlatform) (bool, error) { - platforms, err := platformutil.ListPlatforms(ctx, action.client, thisPlatform.Namespace) +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 } diff --git a/pkg/platform/platform.go b/pkg/platform/platform.go index d566b5e..d273f3d 100644 --- a/pkg/platform/platform.go +++ b/pkg/platform/platform.go @@ -23,6 +23,8 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/util/kubernetes" k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" k8sclient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -80,7 +82,7 @@ func find(ctx context.Context, c k8sclient.Reader, namespace string, active bool // 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) { - lst, err := ListPlatforms(ctx, c, namespace) + lst, err := ListPrimaryPlatforms(ctx, c, namespace) if err != nil { return nil, err } @@ -101,8 +103,24 @@ func findLocal(ctx context.Context, c k8sclient.Reader, namespace string, active return nil, k8serrors.NewNotFound(v1.Resource("IntegrationPlatform"), DefaultPlatformName) } -// ListPlatforms returns all platforms installed in a given namespace (only one will be active) -func ListPlatforms(ctx context.Context, c k8sclient.Reader, namespace string) (*v1.IntegrationPlatformList, error) { +// 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 := v1.NewIntegrationPlatformList() + primaryPlatform, err := labels.NewRequirement(v1.SecondaryPlatformLabel, selection.DoesNotExist, []string{}) + if err != nil { + return nil, err + } + opt := k8sclient.MatchingLabelsSelector{ + labels.NewSelector().Add(*primaryPlatform), + } + if err := c.List(ctx, &lst, k8sclient.InNamespace(namespace), opt); err != nil { + return nil, err + } + return &lst, nil +} + +// ListAllPlatforms returns all platforms installed in a given namespace +func ListAllPlatforms(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 @@ -115,6 +133,14 @@ 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.Labels[v1.SecondaryPlatformLabel]; ok && l == "true" { + return true + } + return false +} + // GetProfile returns the current profile of the platform (if present) or returns the default one for the cluster func GetProfile(p *v1.IntegrationPlatform) v1.TraitProfile { if p.Status.Profile != "" {