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 f589340b15200a577b2308ea984b35e76d5b6fb4 Author: Pasquale Congiusti <[email protected]> AuthorDate: Mon May 31 11:04:48 2021 +0200 feat(cmd/run): check config is not binary Ref #2003 --- pkg/cmd/run.go | 6 ++-- pkg/cmd/run_help.go | 47 ++++++++++++++++++++++++++ pkg/cmd/util_content.go | 2 +- pkg/util/kubernetes/lookup.go | 76 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 126 insertions(+), 5 deletions(-) diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 62793d8..b097cf1 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -597,10 +597,8 @@ func (o *runCmdOptions) updateIntegrationCode(c client.Client, sources []string, } for _, item := range o.Configs { if config, parseErr := ParseConfigOption(item); parseErr == nil { - if config.ConfigType == ConfigOptionTypeFile { - addResource(config.Value, &integration.Spec, o.Compression, v1.ResourceTypeData) - } else { - integration.Spec.AddConfiguration(string(config.ConfigType), config.Value) + if applyConfigOptionErr := ApplyConfigOption(config, &integration.Spec, c, namespace, o.Compression); applyConfigOptionErr != nil { + return nil, applyConfigOptionErr } } else { return nil, parseErr diff --git a/pkg/cmd/run_help.go b/pkg/cmd/run_help.go index 4c91840..2f78b79 100644 --- a/pkg/cmd/run_help.go +++ b/pkg/cmd/run_help.go @@ -18,8 +18,14 @@ limitations under the License. package cmd import ( + "context" "fmt" + "path" "regexp" + + v1 "github.com/apache/camel-k/pkg/apis/camel/v1" + "github.com/apache/camel-k/pkg/client" + "github.com/apache/camel-k/pkg/util/kubernetes" ) // RunConfigOption represents a config option @@ -69,3 +75,44 @@ func ParseConfigOption(item string) (*RunConfigOption, error) { } return newRunConfigOption(cot, groups[2]), nil } + +// ApplyConfigOption will set the proper option behavior to the IntegrationSpec +func ApplyConfigOption(config *RunConfigOption, integrationSpec *v1.IntegrationSpec, c client.Client, namespace string, enableCompression bool) error { + switch config.ConfigType { + case ConfigOptionTypeConfigmap: + cm := kubernetes.LookupConfigmap(context.Background(), c, namespace, config.Value) + if cm == nil { + fmt.Printf("Warn: %s Configmap not found in %s namespace, make sure to provide it before the Integration can run\n", + config.Value, namespace) + } else if cm.BinaryData != nil { + return fmt.Errorf("you cannot provide a binary config, use a text file instead") + } + integrationSpec.AddConfiguration(string(config.ConfigType), config.Value) + case ConfigOptionTypeSecret: + secret := kubernetes.LookupSecret(context.Background(), c, namespace, config.Value) + if secret == nil { + fmt.Printf("Warn: %s Secret not found in %s namespace, make sure to provide it before the Integration can run\n", + config.Value, namespace) + } + integrationSpec.AddConfiguration(string(config.ConfigType), config.Value) + case ConfigOptionTypeFile: + // Don't allow a binary non compressed resource + rawData, contentType, err := loadRawContent(config.Value) + if err != nil { + return err + } + if !enableCompression && isBinary(contentType) { + return fmt.Errorf("you cannot provide a binary config, use a text file or check --resource flag instead") + } + resourceSpec, err := binaryOrTextResource(path.Base(config.Value), rawData, contentType, enableCompression) + if err != nil { + return err + } + integrationSpec.AddResources(resourceSpec) + default: + // Should never reach this + return fmt.Errorf("invalid config option type %s", config.ConfigType) + } + + return nil +} diff --git a/pkg/cmd/util_content.go b/pkg/cmd/util_content.go index c02fda2..62cda96 100644 --- a/pkg/cmd/util_content.go +++ b/pkg/cmd/util_content.go @@ -51,7 +51,7 @@ func loadRawContent(source string) ([]byte, string, error) { case "https": content, err = loadContentHTTP(u) default: - return nil, "", fmt.Errorf("unsupported scheme %s", u.Scheme) + return nil, "", fmt.Errorf("missing file or unsupported scheme %s", u.Scheme) } } diff --git a/pkg/util/kubernetes/lookup.go b/pkg/util/kubernetes/lookup.go new file mode 100644 index 0000000..92b63de --- /dev/null +++ b/pkg/util/kubernetes/lookup.go @@ -0,0 +1,76 @@ +/* +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 kubernetes + +import ( + "context" + + "github.com/apache/camel-k/pkg/client" + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + ctrl "sigs.k8s.io/controller-runtime/pkg/client" +) + +// LookupConfigmap will look for any k8s Configmap with a given name in a given namespace +func LookupConfigmap(ctx context.Context, c client.Client, ns string, name string) *corev1.ConfigMap { + cm := corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: corev1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: ns, + Name: name, + }, + } + key := ctrl.ObjectKey{ + Namespace: ns, + Name: name, + } + if err := c.Get(ctx, key, &cm); err != nil && k8serrors.IsNotFound(err) { + return nil + } else if err != nil { + return nil + } + return &cm +} + +// LookupSecret will look for any k8s Secret with a given name in a given namespace +func LookupSecret(ctx context.Context, c client.Client, ns string, name string) *corev1.Secret { + secret := corev1.Secret{ + TypeMeta: metav1.TypeMeta{ + Kind: "Secret", + APIVersion: corev1.SchemeGroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: ns, + Name: name, + }, + } + key := ctrl.ObjectKey{ + Namespace: ns, + Name: name, + } + if err := c.Get(ctx, key, &secret); err != nil && k8serrors.IsNotFound(err) { + return nil + } else if err != nil { + return nil + } + return &secret +}
