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 e586e1eafe24140baf3e97617f9e68f6f5e36d84 Author: Pasquale Congiusti <[email protected]> AuthorDate: Wed May 26 17:14:36 2021 +0200 feat(cmd/run): --config option flag * Introducing --config [configmap|secret|file]:name * Deprecate --configmap and --secret Ref #2003 --- pkg/cmd/run.go | 61 +++++++++++++++++++++++++++++------------ pkg/cmd/run_help.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ pkg/cmd/run_help_test.go | 46 +++++++++++++++++++++++++++++++ 3 files changed, 160 insertions(+), 18 deletions(-) diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 78129a4..62793d8 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -78,10 +78,11 @@ func newCmdRun(rootCmdOptions *RootCmdOptions) (*cobra.Command, *runCmdOptions) cmd.Flags().StringArrayP("dependency", "d", nil, "A dependency that should be included, e.g., \"-d camel-mail\" for a Camel component, or \"-d mvn:org.my:app:1.0\" for a Maven dependency") cmd.Flags().BoolP("wait", "w", false, "Wait for the integration to be running") cmd.Flags().StringP("kit", "k", "", "The kit used to run the integration") - cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property or properties file (syntax, my-key=my-value | file:/path/to/my-conf.properties)") - cmd.Flags().StringArray("build-property", nil, "Add a build time property or properties file (syntax, my-key=my-value | file:/path/to/my-conf.properties)") - cmd.Flags().StringArray("configmap", nil, "Add a ConfigMap") - cmd.Flags().StringArray("secret", nil, "Add a Secret") + cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property or properties file (syntax: [my-key=my-value|file:/path/to/my-conf.properties])") + cmd.Flags().StringArray("build-property", nil, "Add a build time property or properties file (syntax: [my-key=my-value|file:/path/to/my-conf.properties])") + cmd.Flags().StringArray("config", nil, "Add runtime configuration from a Configmap, a Secret or a file (syntax: [configmap|secret|file]:name)") + cmd.Flags().StringArray("configmap", nil, "[Deprecated] Add a ConfigMap") + cmd.Flags().StringArray("secret", nil, "[Deprecated] Add a Secret") cmd.Flags().StringArray("maven-repository", nil, "Add a maven repository") cmd.Flags().Bool("logs", false, "Print integration logs") cmd.Flags().Bool("sync", false, "Synchronize the local source file with the cluster, republishing at each change") @@ -129,6 +130,7 @@ type runCmdOptions struct { 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"` ConfigMaps []string `mapstructure:"configmaps" yaml:",omitempty"` Secrets []string `mapstructure:"secrets" yaml:",omitempty"` Repositories []string `mapstructure:"maven-repositories" yaml:",omitempty"` @@ -227,8 +229,15 @@ func (o *runCmdOptions) validate() error { // Deprecation warning if o.PropertyFiles != nil { - fmt.Println("Warn: --property-files has been deprecated. You should use --property file:/path/to/conf.properties instead.") + fmt.Println("Warn: --property-file has been deprecated. You should use --property file:/path/to/conf.properties instead.") } + if o.ConfigMaps != nil { + fmt.Println("Warn: --configmap has been deprecated. You should use --config configmap:my-configmap instead.") + } + if o.Secrets != nil { + fmt.Println("Warn: --secret has been deprecated. You should use --config secret:my-secret instead.") + } + err := validatePropertyFiles(o.PropertyFiles) if err != nil { return err @@ -549,19 +558,7 @@ func (o *runCmdOptions) updateIntegrationCode(c client.Client, sources []string, } for _, resource := range o.OpenAPIs { - data, _, compressed, err := loadTextContent(resource, o.Compression) - if err != nil { - return nil, err - } - - integration.Spec.AddResources(v1.ResourceSpec{ - DataSpec: v1.DataSpec{ - Name: path.Base(resource), - Content: data, - Compression: compressed, - }, - Type: v1.ResourceTypeOpenAPI, - }) + addResource(resource, &integration.Spec, o.Compression, v1.ResourceTypeOpenAPI) } for _, item := range o.Dependencies { @@ -598,6 +595,17 @@ func (o *runCmdOptions) updateIntegrationCode(c client.Client, sources []string, for _, item := range o.LoggingLevels { integration.Spec.AddConfiguration("property", "logging.level."+item) } + 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) + } + } else { + return nil, parseErr + } + } for _, item := range o.ConfigMaps { integration.Spec.AddConfiguration("configmap", item) } @@ -681,6 +689,23 @@ func (o *runCmdOptions) updateIntegrationCode(c client.Client, sources []string, return &integration, nil } +func addResource(resourceLocation string, integrationSpec *v1.IntegrationSpec, enableCompression bool, resourceType v1.ResourceType) error { + if data, _, compressed, err := loadTextContent(resourceLocation, enableCompression); err == nil { + integrationSpec.AddResources(v1.ResourceSpec{ + DataSpec: v1.DataSpec{ + Name: path.Base(resourceLocation), + Content: data, + Compression: compressed, + }, + Type: resourceType, + }) + } else { + return err + } + + return nil +} + // The function parse the value and if it is a file (file:/path/), it will parse as property file // otherwise return a single property built from the item passed as `key=value` func extractProperties(value string) (*properties.Properties, error) { diff --git a/pkg/cmd/run_help.go b/pkg/cmd/run_help.go new file mode 100644 index 0000000..4c91840 --- /dev/null +++ b/pkg/cmd/run_help.go @@ -0,0 +1,71 @@ +/* +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 cmd + +import ( + "fmt" + "regexp" +) + +// RunConfigOption represents a config option +type RunConfigOption struct { + ConfigType configOptionType + Value string +} + +type configOptionType string + +const ( + // ConfigOptionTypeConfigmap -- + ConfigOptionTypeConfigmap configOptionType = "configmap" + // ConfigOptionTypeSecret -- + ConfigOptionTypeSecret configOptionType = "secret" + // ConfigOptionTypeFile -- + ConfigOptionTypeFile configOptionType = "file" +) + +var validConfigRegexp = regexp.MustCompile(`^(configmap|secret|file)\:([\w\.\-\_\:\/]+)$`) + +func newRunConfigOption(configType configOptionType, value string) *RunConfigOption { + return &RunConfigOption{ + ConfigType: configType, + Value: value, + } +} + +// ParseConfigOption will parse and return a runConfigOption +func ParseConfigOption(item string) (*RunConfigOption, error) { + if !validConfigRegexp.MatchString(item) { + return nil, fmt.Errorf("could not match configuration %s, must match %v regular expression", item, validConfigRegexp) + } + // Parse the regexp groups + groups := validConfigRegexp.FindStringSubmatch(item) + var cot configOptionType + switch groups[1] { + case "configmap": + cot = ConfigOptionTypeConfigmap + case "secret": + cot = ConfigOptionTypeSecret + case "file": + cot = ConfigOptionTypeFile + default: + // Should never reach this + return nil, fmt.Errorf("invalid config option type %s", groups[1]) + } + return newRunConfigOption(cot, groups[2]), nil +} diff --git a/pkg/cmd/run_help_test.go b/pkg/cmd/run_help_test.go new file mode 100644 index 0000000..39d67f0 --- /dev/null +++ b/pkg/cmd/run_help_test.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 cmd + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestParseConfigOption(t *testing.T) { + validConfigMap := "configmap:my-config_map" + validSecret := "secret:my-secret" + validFile := "file:/tmp/my-file.txt" + notValid := "someprotocol:wrong" + + configmap, err := ParseConfigOption(validConfigMap) + assert.Nil(t, err) + assert.Equal(t, ConfigOptionTypeConfigmap, configmap.ConfigType) + assert.Equal(t, "my-config_map", configmap.Value) + secret, err := ParseConfigOption(validSecret) + assert.Nil(t, err) + assert.Equal(t, ConfigOptionTypeSecret, secret.ConfigType) + assert.Equal(t, "my-secret", secret.Value) + file, err := ParseConfigOption(validFile) + assert.Nil(t, err) + assert.Equal(t, ConfigOptionTypeFile, file.ConfigType) + assert.Equal(t, "/tmp/my-file.txt", file.Value) + _, err = ParseConfigOption(notValid) + assert.NotNil(t, err) +}
