This is an automated email from the ASF dual-hosted git repository. pcongiusti pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit fa3479b34c10728873299356687aeef043207548 Author: Pasquale Congiusti <[email protected]> AuthorDate: Thu Jun 16 17:24:30 2022 +0200 chore(cli): polished promote feature --- pkg/cmd/promote.go | 91 ++++++++++++++++++++++++++++++----------------- pkg/trait/kamelets.go | 24 +++---------- pkg/trait/mount.go | 2 +- pkg/util/kamelets/util.go | 56 +++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 54 deletions(-) diff --git a/pkg/cmd/promote.go b/pkg/cmd/promote.go index b24eafd80..28be8b28b 100644 --- a/pkg/cmd/promote.go +++ b/pkg/cmd/promote.go @@ -27,11 +27,10 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/apache/camel-k/pkg/client" - "github.com/apache/camel-k/pkg/metadata" - "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/camel" + "github.com/apache/camel-k/pkg/util/kamelets" "github.com/apache/camel-k/pkg/util/kubernetes" - "github.com/apache/camel-k/pkg/util/source" + "github.com/apache/camel-k/pkg/util/resource" "github.com/spf13/cobra" corev1 "k8s.io/api/core/v1" k8sclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -120,7 +119,7 @@ func checkOpsCompatibility(cmd *cobra.Command, source, dest map[string]string) e if !compatibleVersions(source["Runtime Version"], dest["Runtime Version"], cmd) { return fmt.Errorf("source (%s) and destination (%s) Camel K runtime versions are not compatible", source["Runtime Version"], dest["Runtime Version"]) } - if source["Registry Address"] != source["Registry Address"] { + if source["Registry Address"] != dest["Registry Address"] { return fmt.Errorf("source (%s) and destination (%s) Camel K container images registries are not the same", source["Registry Address"], dest["Registry Address"]) } @@ -148,27 +147,52 @@ func (o *promoteCmdOptions) validateDestResources(c client.Client, it *v1.Integr var kamelets []string // Mount trait mounts := it.Spec.Traits["mount"] - json.Unmarshal(mounts.Configuration.RawMessage, &traits) + if err := json.Unmarshal(mounts.Configuration.RawMessage, &traits); err != nil { + return err + } for t, v := range traits { - if t == "configs" || t == "resources" { + switch t { + case "configs": for _, c := range v { - //TODO proper parse resources, now it does not account for complex parsing - if strings.HasPrefix(c, "configmap:") { - configmaps = append(configmaps, strings.Split(c, ":")[1]) + if conf, parseErr := resource.ParseConfig(c); parseErr == nil { + if conf.StorageType() == resource.StorageTypeConfigmap { + configmaps = append(configmaps, conf.Name()) + } else if conf.StorageType() == resource.StorageTypeSecret { + secrets = append(secrets, conf.Name()) + } + } else { + return parseErr } - if strings.HasPrefix(c, "secret:") { - secrets = append(secrets, strings.Split(c, ":")[1]) + } + case "resources": + for _, c := range v { + if conf, parseErr := resource.ParseResource(c); parseErr == nil { + if conf.StorageType() == resource.StorageTypeConfigmap { + configmaps = append(configmaps, conf.Name()) + } else if conf.StorageType() == resource.StorageTypeSecret { + secrets = append(secrets, conf.Name()) + } + } else { + return parseErr } } - } else if t == "volumes" { + case "volumes": for _, c := range v { - pvcs = append(pvcs, strings.Split(c, ":")[0]) + if conf, parseErr := resource.ParseVolume(c); parseErr == nil { + if conf.StorageType() == resource.StorageTypePVC { + pvcs = append(pvcs, conf.Name()) + } + } else { + return parseErr + } } } } // Openapi trait openapis := it.Spec.Traits["openapi"] - json.Unmarshal(openapis.Configuration.RawMessage, &traits) + if err := json.Unmarshal(openapis.Configuration.RawMessage, &traits); err != nil { + return err + } for k, v := range traits { for _, c := range v { if k == "configmaps" { @@ -177,7 +201,17 @@ func (o *promoteCmdOptions) validateDestResources(c client.Client, it *v1.Integr } } // Kamelet trait - kamelets = o.listKamelets(c, it) + kameletTrait := it.Spec.Traits["kamelets"] + var kameletListTrait map[string]string + if err := json.Unmarshal(kameletTrait.Configuration.RawMessage, &kameletListTrait); err != nil { + return err + } + kamelets = strings.Split(kameletListTrait["list"], ",") + sourceKamelets, err := o.listKamelets(c, it) + if err != nil { + return err + } + kamelets = append(kamelets, sourceKamelets...) anyError := false var errorTrace string @@ -213,23 +247,14 @@ func (o *promoteCmdOptions) validateDestResources(c client.Client, it *v1.Integr return nil } -func (o *promoteCmdOptions) listKamelets(c client.Client, it *v1.Integration) []string { - // TODO collect any kamelets which may be coming into the kamelet trait as well - var kamelets []string - - sources, _ := kubernetes.ResolveIntegrationSources(o.Context, c, it, &kubernetes.Collection{}) - catalog, _ := camel.DefaultCatalog() - metadata.Each(catalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool { - util.StringSliceUniqueConcat(&kamelets, meta.Kamelets) - return true - }) - - // Check if a Kamelet is configured as default error handler URI - defaultErrorHandlerURI := it.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerAppPropertiesPrefix + ".deadLetterUri") - if defaultErrorHandlerURI != "" { - if strings.HasPrefix(defaultErrorHandlerURI, "kamelet:") { - kamelets = append(kamelets, source.ExtractKamelet(defaultErrorHandlerURI)) - } +func (o *promoteCmdOptions) listKamelets(c client.Client, it *v1.Integration) ([]string, error) { + catalog, err := camel.DefaultCatalog() + if err != nil { + return nil, err + } + kamelets, err := kamelets.ExtractKameletFromSources(o.Context, c, catalog, &kubernetes.Collection{}, it) + if err != nil { + return nil, err } // We must remove any default source/sink @@ -240,7 +265,7 @@ func (o *promoteCmdOptions) listKamelets(c client.Client, it *v1.Integration) [] } } - return filtered + return filtered, nil } func existsCm(ctx context.Context, c client.Client, name string, namespace string) bool { diff --git a/pkg/trait/kamelets.go b/pkg/trait/kamelets.go index a5c1c936b..f8873cd7d 100644 --- a/pkg/trait/kamelets.go +++ b/pkg/trait/kamelets.go @@ -31,13 +31,11 @@ import ( "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" kameletutils "github.com/apache/camel-k/pkg/kamelet" "github.com/apache/camel-k/pkg/kamelet/repository" - "github.com/apache/camel-k/pkg/metadata" "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/digest" "github.com/apache/camel-k/pkg/util/dsl" - "github.com/apache/camel-k/pkg/util/kubernetes" - "github.com/apache/camel-k/pkg/util/source" + "github.com/apache/camel-k/pkg/util/kamelets" ) // The kamelets trait is a platform trait used to inject Kamelets into the integration runtime. @@ -91,23 +89,9 @@ func (t *kameletsTrait) Configure(e *Environment) (bool, error) { } if IsNilOrTrue(t.Auto) { - var kamelets []string - if t.List == "" { - sources, err := kubernetes.ResolveIntegrationSources(e.Ctx, e.Client, e.Integration, e.Resources) - if err != nil { - return false, err - } - metadata.Each(e.CamelCatalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool { - util.StringSliceUniqueConcat(&kamelets, meta.Kamelets) - return true - }) - } - // Check if a Kamelet is configured as default error handler URI - defaultErrorHandlerURI := e.Integration.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerAppPropertiesPrefix + ".deadLetterUri") - if defaultErrorHandlerURI != "" { - if strings.HasPrefix(defaultErrorHandlerURI, "kamelet:") { - kamelets = append(kamelets, source.ExtractKamelet(defaultErrorHandlerURI)) - } + kamelets, err := kamelets.ExtractKameletFromSources(e.Ctx, e.Client, e.CamelCatalog, e.Resources, e.Integration) + if err != nil { + return false, err } if len(kamelets) > 0 { diff --git a/pkg/trait/mount.go b/pkg/trait/mount.go index 6c8976a85..81d58c50f 100644 --- a/pkg/trait/mount.go +++ b/pkg/trait/mount.go @@ -43,7 +43,7 @@ type mountTrait struct { // 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 + // Syntax: [configmap|secret]:name[/key], where name represents the resource name and key optionally represents the resource key to be filtered Configs []string `property:"configs" json:"configs,omitempty"` // 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). diff --git a/pkg/util/kamelets/util.go b/pkg/util/kamelets/util.go new file mode 100644 index 000000000..2db03c7fc --- /dev/null +++ b/pkg/util/kamelets/util.go @@ -0,0 +1,56 @@ +/* +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 kamelets + +import ( + "context" + "strings" + + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + "github.com/apache/camel-k/pkg/client" + "github.com/apache/camel-k/pkg/metadata" + "github.com/apache/camel-k/pkg/util" + "github.com/apache/camel-k/pkg/util/camel" + "github.com/apache/camel-k/pkg/util/kubernetes" + "github.com/apache/camel-k/pkg/util/source" +) + +// ExtractKameletFromSources provide a list of Kamelets referred into the Integration sources. +func ExtractKameletFromSources(context context.Context, c client.Client, catalog *camel.RuntimeCatalog, resources *kubernetes.Collection, it *v1.Integration) ([]string, error) { + var kamelets []string + + sources, err := kubernetes.ResolveIntegrationSources(context, c, it, resources) + if err != nil { + return nil, err + } + metadata.Each(catalog, sources, func(_ int, meta metadata.IntegrationMetadata) bool { + util.StringSliceUniqueConcat(&kamelets, meta.Kamelets) + return true + }) + + // Check if a Kamelet is configured as default error handler URI + defaultErrorHandlerURI := it.Spec.GetConfigurationProperty(v1alpha1.ErrorHandlerAppPropertiesPrefix + ".deadLetterUri") + if defaultErrorHandlerURI != "" { + if strings.HasPrefix(defaultErrorHandlerURI, "kamelet:") { + kamelets = append(kamelets, source.ExtractKamelet(defaultErrorHandlerURI)) + } + } + + return kamelets, nil +}
