This is an automated email from the ASF dual-hosted git repository. nferraro pushed a commit to branch antora in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 7313fa44d6e4a84d7ad24e1ca742bcab32befdb3 Author: lburgazzoli <lburgazz...@gmail.com> AuthorDate: Thu Dec 13 17:10:04 2018 +0100 refactor: consistent env var management in traits --- pkg/client/cmd/install.go | 2 +- pkg/client/cmd/root.go | 1 + pkg/trait/builder.go | 4 +- pkg/trait/builder_test.go | 6 ++- pkg/trait/catalog.go | 6 +-- pkg/trait/debug.go | 3 +- pkg/trait/debug_test.go | 17 +++++-- pkg/trait/deployment.go | 44 +++++++++++------- pkg/trait/environment.go | 36 +++----------- pkg/trait/environment_test.go | 8 ++-- pkg/trait/knative.go | 40 ++++++++++------ pkg/trait/knative_test.go | 24 ++++++---- pkg/trait/springboot.go | 10 ++-- pkg/trait/trait.go | 3 +- pkg/trait/trait_test.go | 2 +- pkg/trait/types.go | 3 +- pkg/trait/util.go | 76 +++++++++++------------------- pkg/util/envvar/envvar.go | 87 ++++++++++++++++++++++++++++++++++ pkg/util/envvar/envvar_test.go | 103 +++++++++++++++++++++++++++++++++++++++++ 19 files changed, 330 insertions(+), 145 deletions(-) diff --git a/pkg/client/cmd/install.go b/pkg/client/cmd/install.go index 2bafe94..0de2ed2 100644 --- a/pkg/client/cmd/install.go +++ b/pkg/client/cmd/install.go @@ -19,10 +19,10 @@ package cmd import ( "fmt" - "github.com/operator-framework/operator-sdk/pkg/k8sclient" "time" "github.com/apache/camel-k/pkg/install" + "github.com/operator-framework/operator-sdk/pkg/k8sclient" "github.com/pkg/errors" "github.com/spf13/cobra" k8serrors "k8s.io/apimachinery/pkg/api/errors" diff --git a/pkg/client/cmd/root.go b/pkg/client/cmd/root.go index ed02838..203876a 100644 --- a/pkg/client/cmd/root.go +++ b/pkg/client/cmd/root.go @@ -19,6 +19,7 @@ package cmd import ( "context" + "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/pkg/errors" "github.com/spf13/cobra" diff --git a/pkg/trait/builder.go b/pkg/trait/builder.go index fd11fa2..0cb22fc 100644 --- a/pkg/trait/builder.go +++ b/pkg/trait/builder.go @@ -18,12 +18,13 @@ limitations under the License. package trait import ( + "regexp" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/apache/camel-k/pkg/builder" "github.com/apache/camel-k/pkg/builder/kaniko" "github.com/apache/camel-k/pkg/builder/s2i" "github.com/apache/camel-k/pkg/platform" - "regexp" ) const ( @@ -103,5 +104,4 @@ func (t *builderTrait) ReplaceHost(ctx *builder.Context) error { func getImageWithOpenShiftHost(image string) string { pattern := regexp.MustCompile(`^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+([:/].*)`) return pattern.ReplaceAllString(image, openshiftDockerRegistryHost+"$1") - return image } diff --git a/pkg/trait/builder_test.go b/pkg/trait/builder_test.go index cb9147f..bf86330 100644 --- a/pkg/trait/builder_test.go +++ b/pkg/trait/builder_test.go @@ -20,6 +20,8 @@ package trait import ( "testing" + "k8s.io/api/core/v1" + "github.com/apache/camel-k/pkg/builder" "github.com/apache/camel-k/pkg/util/kubernetes" @@ -136,7 +138,7 @@ func createBuilderTestEnv(cluster v1alpha1.IntegrationPlatformCluster, strategy }, }, }, - EnvVars: make(map[string]string), + EnvVars: make([]v1.EnvVar, 0), ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } @@ -150,4 +152,4 @@ func TestIPReplacement(t *testing.T) { assert.Equal(t, "10.0.2.3.4/camel-k", getImageWithOpenShiftHost("10.0.2.3.4/camel-k")) assert.Equal(t, "gcr.io/camel-k/camel-k:latest", getImageWithOpenShiftHost("gcr.io/camel-k/camel-k:latest")) assert.Equal(t, "docker.io/camel-k:latest", getImageWithOpenShiftHost("docker.io/camel-k:latest")) -} \ No newline at end of file +} diff --git a/pkg/trait/catalog.go b/pkg/trait/catalog.go index 6ab0ae2..0fd5668 100644 --- a/pkg/trait/catalog.go +++ b/pkg/trait/catalog.go @@ -86,8 +86,8 @@ func (c *Catalog) traitsFor(environment *Environment) []Trait { c.tDependencies, c.tBuilder, c.tSpringBoot, - c.tDeployment, c.tEnvironment, + c.tDeployment, c.tService, c.tRoute, c.tOwner, @@ -98,8 +98,8 @@ func (c *Catalog) traitsFor(environment *Environment) []Trait { c.tDependencies, c.tBuilder, c.tSpringBoot, - c.tDeployment, c.tEnvironment, + c.tDeployment, c.tService, c.tIngress, c.tOwner, @@ -110,9 +110,9 @@ func (c *Catalog) traitsFor(environment *Environment) []Trait { c.tDependencies, c.tBuilder, c.tSpringBoot, + c.tEnvironment, c.tKnative, c.tDeployment, - c.tEnvironment, c.tIstio, c.tOwner, } diff --git a/pkg/trait/debug.go b/pkg/trait/debug.go index b78bcc6..51f5161 100644 --- a/pkg/trait/debug.go +++ b/pkg/trait/debug.go @@ -19,6 +19,7 @@ package trait import ( "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + "github.com/apache/camel-k/pkg/util/envvar" ) type debugTrait struct { @@ -43,7 +44,7 @@ func (t *debugTrait) Configure(e *Environment) (bool, error) { func (t *debugTrait) Apply(e *Environment) error { // this is all that's needed as long as the base image is `fabric8/s2i-java` look into builder/builder.go - e.EnvVars["JAVA_DEBUG"] = True + envvar.SetVal(&e.EnvVars, "JAVA_DEBUG", True) return nil } diff --git a/pkg/trait/debug_test.go b/pkg/trait/debug_test.go index 6c24d82..8283c08 100644 --- a/pkg/trait/debug_test.go +++ b/pkg/trait/debug_test.go @@ -20,6 +20,10 @@ package trait import ( "testing" + "github.com/apache/camel-k/pkg/util/envvar" + + "k8s.io/api/core/v1" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/stretchr/testify/assert" ) @@ -40,7 +44,8 @@ func TestDebugTraitApplicability(t *testing.T) { }, }, }, - EnvVars: make(map[string]string)} + EnvVars: make([]v1.EnvVar, 0), + } trait := newDebugTrait() @@ -56,7 +61,7 @@ func TestDebugTraitApplicability(t *testing.T) { } func TestApplyDebugTrait(t *testing.T) { - env := Environment{ + environment := Environment{ Integration: &v1alpha1.Integration{ Status: v1alpha1.IntegrationStatus{ Phase: v1alpha1.IntegrationPhaseDeploying, @@ -71,10 +76,12 @@ func TestApplyDebugTrait(t *testing.T) { }, }, }, - EnvVars: make(map[string]string)} + EnvVars: make([]v1.EnvVar, 0), + } trait := newDebugTrait() - assert.Nil(t, trait.Apply(&env)) - assert.Equal(t, True, env.EnvVars["JAVA_DEBUG"]) + assert.Nil(t, trait.Apply(&environment)) + assert.NotNil(t, envvar.Get(environment.EnvVars, "JAVA_DEBUG")) + assert.Equal(t, True, envvar.Get(environment.EnvVars, "JAVA_DEBUG").Value) } diff --git a/pkg/trait/deployment.go b/pkg/trait/deployment.go index 7e8d01f..6b33485 100644 --- a/pkg/trait/deployment.go +++ b/pkg/trait/deployment.go @@ -23,6 +23,8 @@ import ( "strconv" "strings" + "github.com/apache/camel-k/pkg/util/envvar" + "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -96,7 +98,11 @@ func (t *deploymentTrait) getConfigMapsFor(e *Environment) []runtime.Object { // combine properties of integration with context, integration // properties have the priority - properties := CombineConfigurationAsMap("property", e.Context, e.Integration) + properties := "" + + VisitKeyValConfigurations("property", e.Context, e.Integration, func(key string, val string) { + properties += fmt.Sprintf("%s=%s\n", key, val) + }) maps = append( maps, @@ -113,7 +119,7 @@ func (t *deploymentTrait) getConfigMapsFor(e *Environment) []runtime.Object { }, }, Data: map[string]string{ - "properties": PropertiesString(properties), + "properties": properties, }, }, ) @@ -194,28 +200,32 @@ func (t *deploymentTrait) getSources(e *Environment) []string { func (t *deploymentTrait) getDeploymentFor(e *Environment) *appsv1.Deployment { sources := t.getSources(e) + environment := make([]corev1.EnvVar, 0) + // combine Environment of integration with context, integration // Environment has the priority - environment := CombineConfigurationAsMap("env", e.Context, e.Integration) + VisitKeyValConfigurations("env", e.Context, e.Integration, func(key string, value string) { + envvar.SetVal(&environment, key, value) + }) // set env vars needed by the runtime - environment["JAVA_MAIN_CLASS"] = "org.apache.camel.k.jvm.Application" + envvar.SetVal(&environment, "JAVA_MAIN_CLASS", "org.apache.camel.k.jvm.Application") // camel-k runtime - environment["CAMEL_K_ROUTES"] = strings.Join(sources, ",") - environment["CAMEL_K_CONF"] = "/etc/camel/conf/application.properties" - environment["CAMEL_K_CONF_D"] = "/etc/camel/conf.d" + envvar.SetVal(&environment, "CAMEL_K_ROUTES", strings.Join(sources, ",")) + envvar.SetVal(&environment, "CAMEL_K_CONF", "/etc/camel/conf/application.properties") + envvar.SetVal(&environment, "CAMEL_K_CONF_D", "/etc/camel/conf.d") // add a dummy env var to trigger deployment if everything but the code // has been changed - environment["CAMEL_K_DIGEST"] = e.Integration.Status.Digest + envvar.SetVal(&environment, "CAMEL_K_DIGEST", e.Integration.Status.Digest) // optimizations - environment["AB_JOLOKIA_OFF"] = True + envvar.SetVal(&environment, "AB_JOLOKIA_OFF", True) // add env vars from traits - for k, v := range e.EnvVars { - environment[k] = v + for _, envVar := range e.EnvVars { + envvar.SetVar(&environment, envVar) } labels := map[string]string{ @@ -248,7 +258,7 @@ func (t *deploymentTrait) getDeploymentFor(e *Environment) *appsv1.Deployment { { Name: e.Integration.Name, Image: e.Integration.Status.Image, - Env: EnvironmentAsEnvVarSlice(environment), + Env: environment, }, }, }, @@ -329,8 +339,7 @@ func (t *deploymentTrait) getDeploymentFor(e *Environment) *appsv1.Deployment { // Volumes :: Additional ConfigMaps // - cmList := CombineConfigurationAsSlice("configmap", e.Context, e.Integration) - for _, cmName := range cmList { + VisitConfigurations("configmap", e.Context, e.Integration, func(cmName string) { cnt++ vols = append(vols, corev1.Volume{ @@ -348,14 +357,13 @@ func (t *deploymentTrait) getDeploymentFor(e *Environment) *appsv1.Deployment { Name: "integration-cm-" + cmName, MountPath: fmt.Sprintf("/etc/camel/conf.d/%03d_%s", cnt, cmName), }) - } + }) // // Volumes :: Additional Secrets // - secretList := CombineConfigurationAsSlice("secret", e.Context, e.Integration) - for _, secretName := range secretList { + VisitConfigurations("secret", e.Context, e.Integration, func(secretName string) { cnt++ vols = append(vols, corev1.Volume{ @@ -371,7 +379,7 @@ func (t *deploymentTrait) getDeploymentFor(e *Environment) *appsv1.Deployment { Name: "integration-secret-" + secretName, MountPath: fmt.Sprintf("/etc/camel/conf.d/%03d_%s", cnt, secretName), }) - } + }) // // Volumes diff --git a/pkg/trait/environment.go b/pkg/trait/environment.go index 9e05d45..67fd522 100644 --- a/pkg/trait/environment.go +++ b/pkg/trait/environment.go @@ -19,9 +19,8 @@ package trait import ( "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" + "github.com/apache/camel-k/pkg/util/envvar" "github.com/apache/camel-k/version" - appsv1 "k8s.io/api/apps/v1" - "k8s.io/api/core/v1" ) type environmentTrait struct { @@ -53,35 +52,12 @@ func (t *environmentTrait) Configure(e *Environment) (bool, error) { } func (t *environmentTrait) Apply(e *Environment) error { - e.Resources.VisitDeployment(func(deployment *appsv1.Deployment) { - for i := 0; i < len(deployment.Spec.Template.Spec.Containers); i++ { - c := &deployment.Spec.Template.Spec.Containers[i] + envvar.SetVal(&e.EnvVars, envVarCamelKVersion, version.Version) - c.Env = append(c.Env, v1.EnvVar{ - Name: envVarCamelKVersion, - Value: version.Version, - }) - - if t.ContainerMeta { - c.Env = append(c.Env, v1.EnvVar{ - Name: envVarNamespace, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "metadata.namespace", - }, - }, - }) - c.Env = append(c.Env, v1.EnvVar{ - Name: envVarPodName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ - FieldPath: "metadata.name", - }, - }, - }) - } - } - }) + if t.ContainerMeta { + envvar.SetValFrom(&e.EnvVars, envVarNamespace, "metadata.namespace") + envvar.SetValFrom(&e.EnvVars, envVarPodName, "metadata.name") + } return nil } diff --git a/pkg/trait/environment_test.go b/pkg/trait/environment_test.go index 4707a96..430bef2 100644 --- a/pkg/trait/environment_test.go +++ b/pkg/trait/environment_test.go @@ -20,6 +20,8 @@ package trait import ( "testing" + corev1 "k8s.io/api/core/v1" + "github.com/apache/camel-k/pkg/util/kubernetes" "k8s.io/api/apps/v1" @@ -44,7 +46,7 @@ func TestDefaultEnvironment(t *testing.T) { Cluster: v1alpha1.IntegrationPlatformClusterOpenShift, }, }, - EnvVars: make(map[string]string), + EnvVars: make([]corev1.EnvVar, 0), ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } @@ -99,7 +101,7 @@ func TestEnabledContainerMetaDataEnvVars(t *testing.T) { Cluster: v1alpha1.IntegrationPlatformClusterOpenShift, }, }, - EnvVars: make(map[string]string), + EnvVars: make([]corev1.EnvVar, 0), ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } @@ -154,7 +156,7 @@ func TestDisabledContainerMetaDataEnvVars(t *testing.T) { Cluster: v1alpha1.IntegrationPlatformClusterOpenShift, }, }, - EnvVars: make(map[string]string), + EnvVars: make([]corev1.EnvVar, 0), ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } diff --git a/pkg/trait/knative.go b/pkg/trait/knative.go index 93e16a0..b31ef07 100644 --- a/pkg/trait/knative.go +++ b/pkg/trait/knative.go @@ -21,6 +21,8 @@ import ( "encoding/json" "fmt" + "github.com/apache/camel-k/pkg/util/envvar" + "strconv" "strings" @@ -110,23 +112,33 @@ func (t *knativeTrait) prepareEnvVars(e *Environment) error { if err != nil { return err } - e.EnvVars["CAMEL_KNATIVE_CONFIGURATION"] = conf + + envvar.SetVal(&e.EnvVars, "CAMEL_KNATIVE_CONFIGURATION", conf) + return nil } func (t *knativeTrait) getServiceFor(e *Environment) *serving.Service { // combine properties of integration with context, integration // properties have the priority - properties := CombineConfigurationAsMap("property", e.Context, e.Integration) + properties := "" + + VisitKeyValConfigurations("property", e.Context, e.Integration, func(key string, val string) { + properties += fmt.Sprintf("%s=%s\n", key, val) + }) + + environment := make([]corev1.EnvVar, 0) // combine Environment of integration with context, integration // Environment has the priority - environment := CombineConfigurationAsMap("env", e.Context, e.Integration) + VisitKeyValConfigurations("env", e.Context, e.Integration, func(key string, value string) { + envvar.SetVal(&environment, key, value) + }) sources := make([]string, 0, len(e.Integration.Spec.Sources)) for i, s := range e.Integration.Spec.Sources { - envName := fmt.Sprintf("KAMEL_K_ROUTE_%03d", i) - environment[envName] = s.Content + envName := fmt.Sprintf("CAMEL_K_ROUTE_%03d", i) + envvar.SetVal(&environment, envName, s.Content) params := make([]string, 0) if s.Language != "" { @@ -145,23 +157,23 @@ func (t *knativeTrait) getServiceFor(e *Environment) *serving.Service { } // set env vars needed by the runtime - environment["JAVA_MAIN_CLASS"] = "org.apache.camel.k.jvm.Application" + envvar.SetVal(&environment, "JAVA_MAIN_CLASS", "org.apache.camel.k.jvm.Application") // camel-k runtime - environment["CAMEL_K_ROUTES"] = strings.Join(sources, ",") - environment["CAMEL_K_CONF"] = "env:CAMEL_K_PROPERTIES" - environment["CAMEL_K_PROPERTIES"] = PropertiesString(properties) + envvar.SetVal(&environment, "CAMEL_K_ROUTES", strings.Join(sources, ",")) + envvar.SetVal(&environment, "CAMEL_K_CONF", "env:CAMEL_K_PROPERTIES") + envvar.SetVal(&environment, "CAMEL_K_PROPERTIES", properties) // add a dummy env var to trigger deployment if everything but the code // has been changed - environment["CAMEL_K_DIGEST"] = e.Integration.Status.Digest + envvar.SetVal(&environment, "CAMEL_K_DIGEST", e.Integration.Status.Digest) // optimizations - environment["AB_JOLOKIA_OFF"] = True + envvar.SetVal(&environment, "AB_JOLOKIA_OFF", True) // add env vars from traits - for k, v := range e.EnvVars { - environment[k] = v + for _, envVar := range e.EnvVars { + envvar.SetVar(&environment, envVar) } labels := map[string]string{ @@ -200,7 +212,7 @@ func (t *knativeTrait) getServiceFor(e *Environment) *serving.Service { Spec: serving.RevisionSpec{ Container: corev1.Container{ Image: e.Integration.Status.Image, - Env: EnvironmentAsEnvVarSlice(environment), + Env: environment, }, }, }, diff --git a/pkg/trait/knative_test.go b/pkg/trait/knative_test.go index f701c88..4fd5c40 100644 --- a/pkg/trait/knative_test.go +++ b/pkg/trait/knative_test.go @@ -20,6 +20,10 @@ package trait import ( "testing" + "github.com/apache/camel-k/pkg/util/envvar" + + "k8s.io/api/core/v1" + "github.com/apache/camel-k/pkg/util" "github.com/apache/camel-k/pkg/util/kubernetes" @@ -33,7 +37,7 @@ import ( func TestKnativeTraitWithCompressedSources(t *testing.T) { content := "H4sIAAAAAAAA/+JKK8rP1VAvycxNLbIqyUzOVtfkUlBQUNAryddQz8lPt8rMS8tX1+QCAAAA//8BAAD//3wZ4pUoAAAA" - env := Environment{ + environment := Environment{ Integration: &v1alpha1.Integration{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -63,33 +67,33 @@ func TestKnativeTraitWithCompressedSources(t *testing.T) { }, }, }, - EnvVars: make(map[string]string), + EnvVars: make([]v1.EnvVar, 0), ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } - err := NewCatalog().apply(&env) + err := NewCatalog().apply(&environment) assert.Nil(t, err) - assert.NotEmpty(t, env.ExecutedTraits) - assert.NotNil(t, env.GetTrait(ID("knative"))) - assert.NotNil(t, env.EnvVars["KAMEL_KNATIVE_CONFIGURATION"]) + assert.NotEmpty(t, environment.ExecutedTraits) + assert.NotNil(t, environment.GetTrait(ID("knative"))) + assert.NotNil(t, envvar.Get(environment.EnvVars, "CAMEL_KNATIVE_CONFIGURATION")) services := 0 - env.Resources.VisitKnativeService(func(service *serving.Service) { + environment.Resources.VisitKnativeService(func(service *serving.Service) { services++ vars := service.Spec.RunLatest.Configuration.RevisionTemplate.Spec.Container.Env routes := util.LookupEnvVar(vars, "CAMEL_K_ROUTES") assert.NotNil(t, routes) - assert.Equal(t, "env:KAMEL_K_ROUTE_000?language=js&compression=true", routes.Value) + assert.Equal(t, "env:CAMEL_K_ROUTE_000?language=js&compression=true", routes.Value) - route := util.LookupEnvVar(vars, "KAMEL_K_ROUTE_000") + route := util.LookupEnvVar(vars, "CAMEL_K_ROUTE_000") assert.NotNil(t, route) assert.Equal(t, content, route.Value) }) assert.True(t, services > 0) - assert.True(t, env.Resources.Size() > 0) + assert.True(t, environment.Resources.Size() > 0) } diff --git a/pkg/trait/springboot.go b/pkg/trait/springboot.go index 116c684..f8d87b9 100644 --- a/pkg/trait/springboot.go +++ b/pkg/trait/springboot.go @@ -21,6 +21,8 @@ import ( "sort" "strings" + "github.com/apache/camel-k/pkg/util/envvar" + "github.com/operator-framework/operator-sdk/pkg/sdk" "github.com/pkg/errors" @@ -75,8 +77,8 @@ func (t *springBootTrait) Apply(e *Environment) error { if e.Integration != nil && e.Integration.Status.Phase == v1alpha1.IntegrationPhaseDeploying { // Override env vars - e.EnvVars["JAVA_MAIN_CLASS"] = "org.springframework.boot.loader.PropertiesLauncher" - e.EnvVars["LOADER_PATH"] = "/deployments/dependencies/" + envvar.SetVal(&e.EnvVars, "JAVA_MAIN_CLASS", "org.springframework.boot.loader.PropertiesLauncher") + envvar.SetVal(&e.EnvVars, "LOADER_PATH", "/deployments/dependencies/") if e.Integration.Spec.Context != "" { name := e.Integration.Spec.Context @@ -96,8 +98,8 @@ func (t *springBootTrait) Apply(e *Environment) error { deps = append(deps, artifact.Target) } - e.EnvVars["LOADER_HOME"] = "/deployments" - e.EnvVars["LOADER_PATH"] = strings.Join(deps, ",") + envvar.SetVal(&e.EnvVars, "LOADER_HOME", "/deployments") + envvar.SetVal(&e.EnvVars, "LOADER_PATH", strings.Join(deps, ",")) } } diff --git a/pkg/trait/trait.go b/pkg/trait/trait.go index 6684319..fdc5428 100644 --- a/pkg/trait/trait.go +++ b/pkg/trait/trait.go @@ -22,6 +22,7 @@ import ( "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/pkg/errors" + "k8s.io/api/core/v1" ) // True -- @@ -75,6 +76,6 @@ func newEnvironment(integration *v1alpha1.Integration, ctx *v1alpha1.Integration Integration: integration, ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), - EnvVars: make(map[string]string), + EnvVars: make([]v1.EnvVar, 0), }, nil } diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go index b48bd37..6c9b89a 100644 --- a/pkg/trait/trait_test.go +++ b/pkg/trait/trait_test.go @@ -192,7 +192,7 @@ func createTestEnv(cluster v1alpha1.IntegrationPlatformCluster, script string) * Cluster: cluster, }, }, - EnvVars: make(map[string]string), + EnvVars: make([]corev1.EnvVar, 0), ExecutedTraits: make([]Trait, 0), Resources: kubernetes.NewCollection(), } diff --git a/pkg/trait/types.go b/pkg/trait/types.go index a81f2f4..bbba5ac 100644 --- a/pkg/trait/types.go +++ b/pkg/trait/types.go @@ -22,6 +22,7 @@ import ( "github.com/apache/camel-k/pkg/builder" "github.com/apache/camel-k/pkg/platform" "github.com/apache/camel-k/pkg/util/kubernetes" + "k8s.io/api/core/v1" ) // Identifiable represent an identifiable type @@ -67,7 +68,7 @@ type Environment struct { Steps []builder.Step BuildDir string ExecutedTraits []Trait - EnvVars map[string]string + EnvVars []v1.EnvVar } // GetTrait -- diff --git a/pkg/trait/util.go b/pkg/trait/util.go index afb8f23..ad6e1d3 100644 --- a/pkg/trait/util.go +++ b/pkg/trait/util.go @@ -18,12 +18,10 @@ limitations under the License. package trait import ( - "fmt" "strings" "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" "github.com/operator-framework/operator-sdk/pkg/sdk" - "k8s.io/api/core/v1" ) // GetIntegrationContext retrieves the context set on the integration @@ -38,39 +36,19 @@ func GetIntegrationContext(integration *v1alpha1.Integration) (*v1alpha1.Integra return &ctx, err } -// PropertiesString -- -func PropertiesString(m map[string]string) string { - properties := "" - for k, v := range m { - properties += fmt.Sprintf("%s=%s\n", k, v) - } - - return properties -} - -// EnvironmentAsEnvVarSlice -- -func EnvironmentAsEnvVarSlice(m map[string]string) []v1.EnvVar { - env := make([]v1.EnvVar, 0, len(m)) - - for k, v := range m { - env = append(env, v1.EnvVar{Name: k, Value: v}) - } - - return env -} +// VisitConfigurations -- +func VisitConfigurations( + configurationType string, + context *v1alpha1.IntegrationContext, + integration *v1alpha1.Integration, + consumer func(string)) { -// CombineConfigurationAsMap -- -func CombineConfigurationAsMap(configurationType string, context *v1alpha1.IntegrationContext, integration *v1alpha1.Integration) map[string]string { - result := make(map[string]string) if context != nil { // Add context properties first so integrations can // override it for _, c := range context.Spec.Configuration { if c.Type == configurationType { - pair := strings.Split(c.Value, "=") - if len(pair) == 2 { - result[pair[0]] = pair[1] - } + consumer(c.Value) } } } @@ -78,40 +56,40 @@ func CombineConfigurationAsMap(configurationType string, context *v1alpha1.Integ if integration != nil { for _, c := range integration.Spec.Configuration { if c.Type == configurationType { - pair := strings.Split(c.Value, "=") - if len(pair) == 2 { - result[pair[0]] = pair[1] - } + consumer(c.Value) } } } - - return result } -// CombineConfigurationAsSlice -- -func CombineConfigurationAsSlice(configurationType string, context *v1alpha1.IntegrationContext, integration *v1alpha1.Integration) []string { - result := make(map[string]bool) +// VisitKeyValConfigurations -- +func VisitKeyValConfigurations( + configurationType string, + context *v1alpha1.IntegrationContext, + integration *v1alpha1.Integration, + consumer func(string, string)) { + if context != nil { // Add context properties first so integrations can // override it for _, c := range context.Spec.Configuration { if c.Type == configurationType { - result[c.Value] = true + pair := strings.Split(c.Value, "=") + if len(pair) == 2 { + consumer(pair[0], pair[1]) + } } } } - for _, c := range integration.Spec.Configuration { - if c.Type == configurationType { - result[c.Value] = true + if integration != nil { + for _, c := range integration.Spec.Configuration { + if c.Type == configurationType { + pair := strings.Split(c.Value, "=") + if len(pair) == 2 { + consumer(pair[0], pair[1]) + } + } } } - - keys := make([]string, 0, len(result)) - for k := range result { - keys = append(keys, k) - } - - return keys } diff --git a/pkg/util/envvar/envvar.go b/pkg/util/envvar/envvar.go new file mode 100644 index 0000000..68f6ba7 --- /dev/null +++ b/pkg/util/envvar/envvar.go @@ -0,0 +1,87 @@ +/* +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 envvar + +import "k8s.io/api/core/v1" + +// Get -- +func Get(vars []v1.EnvVar, name string) *v1.EnvVar { + for i := 0; i < len(vars); i++ { + if vars[i].Name == name { + return &vars[i] + } + } + + return nil +} + +// SetVal -- +func SetVal(vars *[]v1.EnvVar, name string, value string) { + envVar := Get(*vars, name) + + if envVar != nil { + envVar.Value = value + envVar.ValueFrom = nil + } else { + *vars = append(*vars, v1.EnvVar{ + Name: name, + Value: value, + }) + } +} + +// SetVar -- +func SetVar(vars *[]v1.EnvVar, newEnvVar v1.EnvVar) { + envVar := Get(*vars, newEnvVar.Name) + + if envVar != nil { + envVar.Value = newEnvVar.Value + envVar.ValueFrom = nil + + if newEnvVar.ValueFrom != nil { + from := *newEnvVar.ValueFrom + envVar.ValueFrom = &from + } + + } else { + *vars = append(*vars, newEnvVar) + } +} + +// SetValFrom -- +func SetValFrom(vars *[]v1.EnvVar, name string, path string) { + envVar := Get(*vars, name) + + if envVar != nil { + envVar.Value = "" + envVar.ValueFrom = &v1.EnvVarSource{ + FieldRef: &v1.ObjectFieldSelector{ + FieldPath: path, + }, + } + } else { + *vars = append(*vars, v1.EnvVar{ + Name: name, + ValueFrom: &v1.EnvVarSource{ + FieldRef: &v1.ObjectFieldSelector{ + FieldPath: path, + }, + }, + }) + } +} diff --git a/pkg/util/envvar/envvar_test.go b/pkg/util/envvar/envvar_test.go new file mode 100644 index 0000000..8d98c49 --- /dev/null +++ b/pkg/util/envvar/envvar_test.go @@ -0,0 +1,103 @@ +/* +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 envvar + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "k8s.io/api/core/v1" +) + +func TestGetEnvVar(t *testing.T) { + vars := []v1.EnvVar{ + { + Name: "MyEnv", + Value: "MyValue", + }, + } + + ev := Get(vars, "MyEnv") + + assert.NotNil(t, ev) + assert.Equal(t, "MyValue", ev.Value) + assert.Nil(t, ev.ValueFrom) + + assert.Nil(t, Get(vars, "NotMyEnv")) +} + +func TestModifyEnvVar(t *testing.T) { + vars := []v1.EnvVar{ + { + Name: "MyEnv", + Value: "MyValue", + }, + } + + ev := Get(vars, "MyEnv") + assert.NotNil(t, ev) + assert.Equal(t, "MyValue", ev.Value) + + ev.Value = "MyNewValue" + + ev = Get(vars, "MyEnv") + assert.NotNil(t, ev) + assert.Equal(t, "MyNewValue", ev.Value) +} + +func TestSetEnvVar(t *testing.T) { + vars := []v1.EnvVar{ + { + Name: "MyEnv", + Value: "MyValue", + }, + } + + ev := Get(vars, "MyEnv") + assert.NotNil(t, ev) + assert.Equal(t, "MyValue", ev.Value) + assert.Nil(t, ev.ValueFrom) + + SetVal(&vars, "MyEnv", "MyNewValue") + + ev = Get(vars, "MyEnv") + assert.NotNil(t, ev) + assert.Equal(t, "MyNewValue", ev.Value) + assert.Nil(t, ev.ValueFrom) + + SetVal(&vars, "MyNewEnv", "MyNewNewValue") + + ev = Get(vars, "MyEnv") + assert.NotNil(t, ev) + assert.Equal(t, "MyNewValue", ev.Value) + assert.Nil(t, ev.ValueFrom) + + ev = Get(vars, "MyNewEnv") + assert.NotNil(t, ev) + assert.Equal(t, "MyNewNewValue", ev.Value) + assert.Nil(t, ev.ValueFrom) + + SetValFrom(&vars, "MyNewEnv", "metadata.namespace") + + ev = Get(vars, "MyNewEnv") + assert.NotNil(t, ev) + assert.Equal(t, "", ev.Value) + assert.NotNil(t, ev.ValueFrom) + assert.Equal(t, "metadata.namespace", ev.ValueFrom.FieldRef.FieldPath) +}