This is an automated email from the ASF dual-hosted git repository.
gfournier pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
The following commit(s) were added to refs/heads/main by this push:
new 9ea0ef93f feat(trait): support Camel cloud native properties
9ea0ef93f is described below
commit 9ea0ef93fa70358d30c980ab582ffb2eb46c0c67
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Sat Oct 19 12:20:02 2024 +0200
feat(trait): support Camel cloud native properties
Beside that, we're deprecating the access to Secret and Configmap by either
the CLI or the operator
Closes #5863
---
.../pages/configuration/build-time-properties.adoc | 66 +-------
.../ROOT/pages/configuration/camel-properties.adoc | 65 +-------
pkg/cmd/run.go | 102 +++++++-----
pkg/cmd/run_support.go | 9 ++
pkg/cmd/run_test.go | 5 +-
pkg/trait/camel.go | 38 +++--
pkg/trait/container.go | 6 -
pkg/trait/mount.go | 173 +++++++++++++++++++-
pkg/trait/mount_test.go | 164 +++++++++++++++++++
pkg/trait/trait_test.go | 174 ---------------------
pkg/trait/trait_types.go | 152 +-----------------
pkg/trait/trait_types_test.go | 13 --
pkg/util/kubernetes/lookup.go | 2 +
13 files changed, 439 insertions(+), 530 deletions(-)
diff --git a/docs/modules/ROOT/pages/configuration/build-time-properties.adoc
b/docs/modules/ROOT/pages/configuration/build-time-properties.adoc
index 88c3991c6..7c9f99c26 100644
--- a/docs/modules/ROOT/pages/configuration/build-time-properties.adoc
+++ b/docs/modules/ROOT/pages/configuration/build-time-properties.adoc
@@ -60,74 +60,10 @@ kamel run --build-property=file:quarkus.properties
build-property-route.yaml
The property file is parsed and its properties configured on the
`Integration`. As soon as the application starts, you will see the log with the
expected configuration.
-[[build-time-configmap]]
-== Property from ConfigMap/Secret
-
-In case some build-time properties are stored into a `Configmap` or a
`Secret`, you can use the `--build-property` flag with a value of type
respectively _configmap:name-of-configmap_ or _secret:name-of-secret_ to refer
to the specific resource to use as build-time properties.
-
-As an example, let's create a `Configmap` named _my-cm-bp_ containing the
build-time properties to load. You can alternatively use any `Configmap` you've
already stored in your cluster:
-
-----
-kubectl create configmap my-cm-bp
--from-literal=quarkus.application.name="my-great-application"
--from-literal=quarkus.banner.enabled="true"
-----
-
-Here, as an example we have create a configmap with 2 `Quarkus` properties.
-
-[source,yaml]
-.build-property-route.yaml
-----
-- from:
- uri: "timer:build-property"
- steps:
- - setBody:
- simple: "The application name: {{quarkus.application.name}}"
- - to: "log:info"
-----
-
-The `quarkus.banner.enabled` is configured to show the banner during the
`Integration` startup. Let's use `--build-property` flag in conjunction with
file:
-
-----
-kamel run --build-property=configmap:my-cm-bp build-property-route.yaml
-----
-
-The key-value pairs of the `ConfigMap` are loaded and used as build-time
properties of the `Integration`. As soon as the application starts, you will
see the log with the expected configuration.
-
-[[build-time-configmap-as-file]]
-== Property from ConfigMap/Secret as file
-
-When you have a lot of key-value pairs to store into a given
`ConfigMap`/`Secret`, you may consider storing some build-time properties as a
file into a specific key-value pair for the sake of simplicity.
-
-The only constraint is to use `.properties` as a suffix of the key to indicate
that the value is actually a property file, not a simple value.
-
-As an example, let's use the same `Integration` as the previous section but
with a `ConfigMap` that contains all the properties into the same key-value
pair.
-
-For this we need a properties file as next:
-
-[source,properties]
-.quarkus.properties
-----
-quarkus.application.name = my-super-application
-quarkus.banner.enabled = true
-----
-
-That we will load into a specific `ConfigMap` using the following command:
-
-----
-kubectl create configmap my-cm-bps --from-file=quarkus.properties
-----
-
-Then we launch the `run` command with the `--build-property` flag whose value
matches with the appropriate syntax to refer to `my-cm-bps`:
-
-----
-kamel run --build-property configmap:my-cm-bps build-property-route.yaml
-----
-
-The value of the key-value of the `ConfigMap` is loaded as a property file and
used as build-time properties of the `Integration`. You will see the log with
the expected configuration.
-
[[build-time-props-file-precedence]]
== Property collision priority
-If you have a property repeated more than once, the general rule is that the
last one declared in your `kamel run` statement will be taken in consideration.
If the same property is found both in a single option declaration and inside a
file/configmap/secret, then, the single option will have higher priority and
will be used.
+If you have a property repeated more than once, the general rule is that the
last one declared in your `kamel run` statement will be taken in consideration.
If the same property is found both in a single option declaration and inside a
file, then, the single option will have higher priority and will be used.
[[build-time-runtime-conf]]
== Run time properties
diff --git a/docs/modules/ROOT/pages/configuration/camel-properties.adoc
b/docs/modules/ROOT/pages/configuration/camel-properties.adoc
index d474220f8..254b360c7 100644
--- a/docs/modules/ROOT/pages/configuration/camel-properties.adoc
+++ b/docs/modules/ROOT/pages/configuration/camel-properties.adoc
@@ -83,73 +83,12 @@ The property file is parsed and its properties configured
on the `Integration`.
[[runtime-configmap]]
== Property from ConfigMap/Secret
-In case some runtime properties are stored into a `Configmap` or a `Secret`,
you can use the `--property` flag with a value of type respectively
_configmap:name-of-configmap_ or _secret:name-of-secret_ to refer to the
specific resource to use as runtime properties.
-
-As an example, let's create a `Configmap` named _my-cm-rp_ containing the
runtime properties to load. You can alternatively use any `Configmap` you've
already stored in your cluster:
-
-----
-kubectl create configmap my-cm-rp --from-literal=name="Will Smith"
--from-literal=period="2000"
-----
-
-In our `Integration` we can simply refer to the properties defined in the
`ConfigMap` as we'd do with any other property:
-
-[source,yaml]
-.config-property-configmap-route.yaml
-----
-- from:
- uri: "timer:property"
- parameters:
- period: "{{period}}"
- steps:
- - setBody:
- simple: "Hello {{name}}!"
- - to: "log:info"
-----
-
-Then we launch the `run` command with the `--property` flag whose value
matches with the appropriate syntax to refer to `my-cm-rp`:
-
-----
-kamel run --property configmap:my-cm-rp config-property-configmap-route.yaml
-----
-
-The key-value pairs of the `ConfigMap` are loaded and used as runtime
properties of the `Integration`. As soon as the application starts, you will
see the log with the expected message.
-
-[[runtime-configmap-as-file]]
-== Property from ConfigMap/Secret as file
-
-When you have a lot of key-value pairs to store into a given
`ConfigMap`/`Secret`, you may consider storing some runtime properties as a
file into a specific key-value pair for the sake of simplicity.
-
-The only constraint is to use `.properties` as a suffix of the key to indicate
that the value is actually a property file, not a simple value.
-
-As an example, let's use the same `Integration` as the previous section but
with a `ConfigMap` that contains all the properties into the same key-value
pair.
-
-For this we need a properties file as next:
-
-[source,text]
-.some.properties
-----
-name=John Smith
-period=2000
-----
-
-That we will load into a specific `ConfigMap` using the following command:
-
-----
-kubectl create configmap my-cm-rps --from-file=some.properties
-----
-
-Then we launch the `run` command with the `--property` flag whose value
matches with the appropriate syntax to refer to `my-cm-rps`:
-
-----
-kamel run --property configmap:my-cm-rps config-property-configmap-route.yaml
-----
-
-The value of the key-value of the `ConfigMap` is loaded as a property file and
used as runtime properties of the `Integration`. As soon as the application
starts, you will see the log with the expected message.
+In case some runtime properties are stored into a `Configmap` or a `Secret`,
you can use the `--config` parameter with a value of type respectively
_configmap:name-of-configmap_ or _secret:name-of-secret_ to refer to the
specific resource to use as runtime properties. See more advanced details on
the `mount` trait.
[[runtime-props-file-precedence]]
== Property collision priority
-If you have a property repeated more than once, the general rule is that the
last one declared in your `kamel run` statement will be taken in consideration.
If the same property is found both in a single option declaration and inside a
file/configmap/secret, then, the single option will have higher priority and
will be used.
+If you have a property repeated more than once, the general rule is that the
last one declared in your `kamel run` statement will be taken in consideration.
If the same property is found both in a single option declaration and inside a
file, then, the single option will have higher priority and will be used.
[[runtime-build-time-conf]]
== Build time properties
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index b4667868d..b416b9803 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -82,14 +82,22 @@ func newCmdRun(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *runCmdOptions)
cmd.Flags().String("name", "", "The integration name")
cmd.Flags().String("image", "", "An image built externally (ie, via
CICD). Enabling it will skip the Integration build phase.")
- cmd.Flags().StringArrayP("connect", "c", nil, "A Service that the
integration should bind to, specified as
[[apigroup/]version:]kind:[namespace/]name")
+ // Deprecated: service binding parameter won't be supported in future
releases.
+ cmd.Flags().StringArrayP("connect", "c", nil, "A Service that the
integration should bind to, specified as
[[apigroup/]version:]kind:[namespace/]name."+
+ "Deprecated: service binding won't be supported in future
releases.")
cmd.Flags().StringArrayP("dependency", "d", nil, `A dependency that
should be included, e.g., "-d camel:mail" for a Camel component, "-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 from a path, a config map or a secret (syntax:
[my-key=my-value|file:/path/to/my-conf.properties|[configmap|secret]:name])")
- cmd.Flags().StringArray("build-property", nil, "Add a build time
property or properties file from a path, a config map or a secret (syntax:
[my-key=my-value|file:/path/to/my-conf.properties|[configmap|secret]:name]])")
- cmd.Flags().StringArray("config", nil, "Add a runtime configuration
from a Configmap or a Secret (syntax: [configmap|secret]:name[/key], where name
represents the configmap/secret name and key optionally represents the
configmap/secret key to be filtered)")
- cmd.Flags().StringArray("resource", nil, "Add a runtime resource from a
Configmap or a Secret (syntax: [configmap|secret]:name[/key][@path], where name
represents the configmap/secret name, key optionally represents the
configmap/secret key to be filtered and path represents the destination path)")
+ cmd.Flags().StringArrayP("property", "p", nil, "Add a runtime property
or a local properties file from a path "+
+ "(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 from a path "+
+ "(syntax: [my-key=my-value|file:/path/to/my-conf.properties])")
+ cmd.Flags().StringArray("config", nil, "Add a runtime configuration
from a Configmap or a Secret "+
+ "(syntax: [configmap|secret]:name[/key], where name represents
the configmap/secret name and key optionally "+
+ "represents the configmap/secret key to be filtered)")
+ cmd.Flags().StringArray("resource", nil, "Add a runtime resource from a
Configmap or a Secret "+
+ "(syntax: [configmap|secret]:name[/key][@path], where name
represents the configmap/secret name, "+
+ "key optionally represents the configmap/secret key to be
filtered and path represents the destination path)")
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")
@@ -121,38 +129,41 @@ func newCmdRun(rootCmdOptions *RootCmdOptions)
(*cobra.Command, *runCmdOptions)
type runCmdOptions struct {
*RootCmdOptions `json:"-"`
- Compression bool `mapstructure:"compression"
yaml:",omitempty"`
- Wait bool `mapstructure:"wait" yaml:",omitempty"`
- Logs bool `mapstructure:"logs" yaml:",omitempty"`
- Sync bool `mapstructure:"sync" yaml:",omitempty"`
- Dev bool `mapstructure:"dev" yaml:",omitempty"`
- UseFlows bool `mapstructure:"use-flows" yaml:",omitempty"`
- Save bool `mapstructure:"save" yaml:",omitempty"
kamel:"omitsave"`
- IntegrationKit string `mapstructure:"kit" yaml:",omitempty"`
- IntegrationName string `mapstructure:"name" yaml:",omitempty"`
- ContainerImage string `mapstructure:"image" yaml:",omitempty"`
- Profile string `mapstructure:"profile" yaml:",omitempty"`
- IntegrationProfile string `mapstructure:"integration-profile"
yaml:",omitempty"`
- OperatorID string `mapstructure:"operator-id"
yaml:",omitempty"`
- OutputFormat string `mapstructure:"output" yaml:",omitempty"`
- PodTemplate string `mapstructure:"pod-template"
yaml:",omitempty"`
- ServiceAccount string `mapstructure:"service-account"
yaml:",omitempty"`
- Connects []string `mapstructure:"connects" yaml:",omitempty"`
- Resources []string `mapstructure:"resources" yaml:",omitempty"`
- OpenAPIs []string `mapstructure:"open-apis" yaml:",omitempty"`
- 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"`
- Repositories []string `mapstructure:"maven-repositories"
yaml:",omitempty"`
- Traits []string `mapstructure:"traits" yaml:",omitempty"`
- Volumes []string `mapstructure:"volumes" yaml:",omitempty"`
- EnvVars []string `mapstructure:"envs" yaml:",omitempty"`
- Labels []string `mapstructure:"labels" yaml:",omitempty"`
- Annotations []string `mapstructure:"annotations"
yaml:",omitempty"`
- Sources []string `mapstructure:"sources" yaml:",omitempty"`
- RegistryOptions url.Values
- Force bool `mapstructure:"force" yaml:",omitempty"`
+ Compression bool `mapstructure:"compression" yaml:",omitempty"`
+ Wait bool `mapstructure:"wait" yaml:",omitempty"`
+ Logs bool `mapstructure:"logs" yaml:",omitempty"`
+ Sync bool `mapstructure:"sync" yaml:",omitempty"`
+ Dev bool `mapstructure:"dev" yaml:",omitempty"`
+ UseFlows bool `mapstructure:"use-flows" yaml:",omitempty"`
+ Save bool `mapstructure:"save" yaml:",omitempty"
kamel:"omitsave"`
+ IntegrationKit string `mapstructure:"kit" yaml:",omitempty"`
+ IntegrationName string `mapstructure:"name" yaml:",omitempty"`
+ ContainerImage string `mapstructure:"image" yaml:",omitempty"`
+ Profile string `mapstructure:"profile" yaml:",omitempty"`
+ IntegrationProfile string `mapstructure:"integration-profile"
yaml:",omitempty"`
+ OperatorID string `mapstructure:"operator-id" yaml:",omitempty"`
+ OutputFormat string `mapstructure:"output" yaml:",omitempty"`
+ PodTemplate string `mapstructure:"pod-template"
yaml:",omitempty"`
+ ServiceAccount string `mapstructure:"service-account"
yaml:",omitempty"`
+ // Deprecated: service binding parameter won't be supported in future
releases.
+ Connects []string `mapstructure:"connects" yaml:",omitempty"`
+ Resources []string `mapstructure:"resources" yaml:",omitempty"`
+ // Deprecated: openapi parameter won't be supported in future releases.
+ OpenAPIs []string `mapstructure:"open-apis" yaml:",omitempty"`
+ 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"`
+ Repositories []string `mapstructure:"maven-repositories"
yaml:",omitempty"`
+ Traits []string `mapstructure:"traits" yaml:",omitempty"`
+ Volumes []string `mapstructure:"volumes" yaml:",omitempty"`
+ EnvVars []string `mapstructure:"envs" yaml:",omitempty"`
+ Labels []string `mapstructure:"labels" yaml:",omitempty"`
+ Annotations []string `mapstructure:"annotations" yaml:",omitempty"`
+ Sources []string `mapstructure:"sources" yaml:",omitempty"`
+ // Deprecated: registry parameter no longer in use.
+ RegistryOptions url.Values
+ Force bool `mapstructure:"force" yaml:",omitempty"`
}
func (o *runCmdOptions) decode(cmd *cobra.Command, args []string) error {
@@ -275,6 +286,23 @@ func (o *runCmdOptions) validate(cmd *cobra.Command) error
{
}
}
+ for i, property := range o.Properties {
+ // We support only --config
+ if strings.HasPrefix(property, "configmap:") ||
strings.HasPrefix(property, "secret:") {
+ o.Configs = append(o.Configs, property)
+ // clean it to avoid further processing
+ o.Properties[i] = ""
+ fmt.Fprintf(cmd.OutOrStdout(), "Property %s is
deprecated: use --config %s instead\n", property, property)
+ }
+ }
+
+ for _, bp := range o.BuildProperties {
+ // Deprecated: to be removed
+ if strings.HasPrefix(bp, "configmap:") || strings.HasPrefix(bp,
"secret:") {
+ fmt.Fprintf(cmd.OutOrStdout(), "Build property %s is
deprecated. It will be removed from future releases.\n", bp)
+ }
+ }
+
var client client.Client
if !isOfflineCommand(cmd) {
client, err = o.GetCmdClient()
diff --git a/pkg/cmd/run_support.go b/pkg/cmd/run_support.go
index af2d7a3fe..358e84fd0 100644
--- a/pkg/cmd/run_support.go
+++ b/pkg/cmd/run_support.go
@@ -76,7 +76,11 @@ func keyValueProps(value string) (*properties.Properties,
error) {
return properties.Load([]byte(value), properties.UTF8)
}
+// Deprecated: won't be supported in future releases.
func loadPropertiesFromSecret(ctx context.Context, c client.Client, ns string,
name string) (*properties.Properties, error) {
+ if c == nil {
+ return nil, fmt.Errorf("cannot inspect Secrets in offline mode")
+ }
secret := kubernetes.LookupSecret(ctx, c, ns, name)
if secret == nil {
return nil, fmt.Errorf("%s secret not found in %s namespace,
make sure to provide it before the Integration can run", name, ns)
@@ -88,7 +92,11 @@ func loadPropertiesFromSecret(ctx context.Context, c
client.Client, ns string, n
})
}
+// Deprecated: won't be supported in future releases.
func loadPropertiesFromConfigMap(ctx context.Context, c client.Client, ns
string, name string) (*properties.Properties, error) {
+ if c == nil {
+ return nil, fmt.Errorf("cannot inspect Configmaps in offline
mode")
+ }
cm := kubernetes.LookupConfigmap(ctx, c, ns, name)
if cm == nil {
return nil, fmt.Errorf("%s configmap not found in %s namespace,
make sure to provide it before the Integration can run", name, ns)
@@ -98,6 +106,7 @@ func loadPropertiesFromConfigMap(ctx context.Context, c
client.Client, ns string
func(v reflect.Value) (*properties.Properties, error) { return
keyValueProps(v.String()) })
}
+// Deprecated: func supporting other deprecated funcs.
func fromMapToProperties(data interface{}, toString func(reflect.Value)
string, loadProperties func(reflect.Value) (*properties.Properties, error))
(*properties.Properties, error) {
result := properties.NewProperties()
m := reflect.ValueOf(data)
diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go
index 03a63c456..dfee3e71c 100644
--- a/pkg/cmd/run_test.go
+++ b/pkg/cmd/run_test.go
@@ -625,7 +625,7 @@ func TestTrait(t *testing.T) {
fileName := filepath.Base(tmpFile.Name())
runCmdOptions, runCmd, _ := initializeRunCmdOptionsWithOutput(t)
- output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(),
"-o", "yaml", "-t", "mount.configs=configmap:my-cm", "--connect",
"my-service-binding")
+ output, err := test.ExecuteCommand(runCmd, cmdRun, tmpFile.Name(),
"-o", "yaml", "-t", "mount.configs=configmap:my-cm")
assert.Equal(t, "yaml", runCmdOptions.OutputFormat)
require.NoError(t, err)
@@ -646,9 +646,6 @@ spec:
mount:
configs:
- configmap:my-cm
- service-binding:
- services:
- - my-service-binding
status: {}
`, fileName, fileName), output)
}
diff --git a/pkg/trait/camel.go b/pkg/trait/camel.go
index df94312ae..53eccf51c 100644
--- a/pkg/trait/camel.go
+++ b/pkg/trait/camel.go
@@ -135,9 +135,7 @@ func (t *camelTrait) Apply(e *Environment) error {
}
if e.IntegrationInRunningPhases() {
- // Get all resources
- maps := t.computeConfigMaps(e)
- e.Resources.AddAll(maps)
+ e.Resources.AddAll(t.computeUserProperties(e))
}
return nil
}
@@ -181,7 +179,23 @@ func (t *camelTrait) loadOrCreateCatalog(e *Environment,
runtimeVersion string)
return nil
}
-func (t *camelTrait) computeConfigMaps(e *Environment) []ctrl.Object {
+func determineRuntimeVersion(e *Environment) (string, error) {
+ if e.Integration != nil && e.Integration.Status.RuntimeVersion != "" {
+ return e.Integration.Status.RuntimeVersion, nil
+ }
+ if e.IntegrationKit != nil && e.IntegrationKit.Status.RuntimeVersion !=
"" {
+ return e.IntegrationKit.Status.RuntimeVersion, nil
+ }
+ if e.IntegrationProfile != nil &&
e.IntegrationProfile.Status.Build.RuntimeVersion != "" {
+ return e.IntegrationProfile.Status.Build.RuntimeVersion, nil
+ }
+ if e.Platform != nil && e.Platform.Status.Build.RuntimeVersion != "" {
+ return e.Platform.Status.Build.RuntimeVersion, nil
+ }
+ return "", errors.New("unable to determine runtime version")
+}
+
+func (t *camelTrait) computeUserProperties(e *Environment) []ctrl.Object {
sources := e.Integration.AllSources()
maps := make([]ctrl.Object, 0, len(sources)+1)
@@ -261,19 +275,3 @@ func (t *camelTrait) computeConfigMaps(e *Environment)
[]ctrl.Object {
return maps
}
-
-func determineRuntimeVersion(e *Environment) (string, error) {
- if e.Integration != nil && e.Integration.Status.RuntimeVersion != "" {
- return e.Integration.Status.RuntimeVersion, nil
- }
- if e.IntegrationKit != nil && e.IntegrationKit.Status.RuntimeVersion !=
"" {
- return e.IntegrationKit.Status.RuntimeVersion, nil
- }
- if e.IntegrationProfile != nil &&
e.IntegrationProfile.Status.Build.RuntimeVersion != "" {
- return e.IntegrationProfile.Status.Build.RuntimeVersion, nil
- }
- if e.Platform != nil && e.Platform.Status.Build.RuntimeVersion != "" {
- return e.Platform.Status.Build.RuntimeVersion, nil
- }
- return "", errors.New("unable to determine runtime version")
-}
diff --git a/pkg/trait/container.go b/pkg/trait/container.go
index f3f24deb3..927ea0560 100644
--- a/pkg/trait/container.go
+++ b/pkg/trait/container.go
@@ -188,12 +188,6 @@ func (t *containerTrait) configureContainer(e
*Environment) error {
}); err != nil {
return err
}
- e.addSourcesProperties()
- if props, err := e.computeApplicationProperties(); err != nil {
- return err
- } else if props != nil {
- e.Resources.Add(props)
- }
t.configureResources(&container)
if knative || ptr.Deref(t.Expose, false) {
t.configureService(e, &container, knative)
diff --git a/pkg/trait/mount.go b/pkg/trait/mount.go
index 33a9b85fc..b15c9765d 100644
--- a/pkg/trait/mount.go
+++ b/pkg/trait/mount.go
@@ -19,6 +19,7 @@ package trait
import (
"fmt"
+ "path"
"path/filepath"
"strings"
@@ -27,12 +28,17 @@ import (
corev1 "k8s.io/api/core/v1"
storagev1 "k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/api/resource"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
serving "knative.dev/serving/pkg/apis/serving/v1"
+ v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
"github.com/apache/camel-k/v2/pkg/util/boolean"
+ "github.com/apache/camel-k/v2/pkg/util/camel"
"github.com/apache/camel-k/v2/pkg/util/kubernetes"
+ "github.com/apache/camel-k/v2/pkg/util/log"
+ "github.com/apache/camel-k/v2/pkg/util/property"
utilResource "github.com/apache/camel-k/v2/pkg/util/resource"
)
@@ -112,22 +118,34 @@ func (t *mountTrait) Apply(e *Environment) error {
}
if visited {
- // Volumes declared in the Integration resources
- e.configureVolumesAndMounts(volumes, &container.VolumeMounts)
// Volumes declared in the trait config/resource options
+ // as this func influences the application.properties
+ // must be set as the first one to execute
err := t.configureVolumesAndMounts(e, volumes,
&container.VolumeMounts)
if err != nil {
return err
}
+ // Here we configure the application.properties
+ t.addSourcesProperties(e)
+ if props, err := t.computeApplicationProperties(e); err != nil {
+ return err
+ } else if props != nil {
+ e.Resources.Add(props)
+ }
+ // Volumes declared in the Integration resources (including the
application.properties Configmap)
+ t.configureCamelVolumesAndMounts(e, volumes,
&container.VolumeMounts)
}
return nil
}
+// configureVolumesAndMounts is in charge to mount volumes and mounts coming
from the trait configuration.
func (t *mountTrait) configureVolumesAndMounts(e *Environment, vols
*[]corev1.Volume, mnts *[]corev1.VolumeMount) error {
for _, c := range t.Configs {
if conf, parseErr := utilResource.ParseConfig(c); parseErr ==
nil {
- t.mountResource(vols, mnts, conf)
+ // Let Camel parse these resources as properties
+ destFilePath := t.mountResource(vols, mnts, conf)
+ e.appendCloudPropertiesLocation(destFilePath)
} else {
return parseErr
}
@@ -158,7 +176,78 @@ func (t *mountTrait) configureVolumesAndMounts(e
*Environment, vols *[]corev1.Vo
return nil
}
-func (t *mountTrait) mountResource(vols *[]corev1.Volume, mnts
*[]corev1.VolumeMount, conf *utilResource.Config) {
+// configureCamelVolumesAndMounts is in charge to mount volumes and mounts
coming from Camel configuration
+// (ie, sources, properties, kamelets, etcetera).
+func (t *mountTrait) configureCamelVolumesAndMounts(e *Environment, vols
*[]corev1.Volume, mnts *[]corev1.VolumeMount) {
+ // Sources
+ idx := 0
+ for _, s := range e.Integration.AllSources() {
+ // We don't process routes embedded (native) or Kamelets
+ if e.isEmbedded(s) || s.IsGeneratedFromKamelet() {
+ continue
+ }
+ // Routes are copied under /etc/camel/sources and discovered by
the runtime accordingly
+ cmName := fmt.Sprintf("%s-source-%03d", e.Integration.Name, idx)
+ if s.ContentRef != "" {
+ cmName = s.ContentRef
+ }
+ cmKey := "content"
+ if s.ContentKey != "" {
+ cmKey = s.ContentKey
+ }
+ resName := strings.TrimPrefix(s.Name, "/")
+ refName := fmt.Sprintf("i-source-%03d", idx)
+ resPath := filepath.Join(camel.SourcesMountPath, resName)
+ vol := getVolume(refName, "configmap", cmName, cmKey, resName)
+ mnt := getMount(refName, resPath, resName, true)
+
+ *vols = append(*vols, *vol)
+ *mnts = append(*mnts, *mnt)
+ idx++
+ }
+ // Resources (likely application properties or kamelets)
+ if e.Resources != nil {
+ e.Resources.VisitConfigMap(func(configMap *corev1.ConfigMap) {
+ switch configMap.Labels[kubernetes.ConfigMapTypeLabel] {
+ case CamelPropertiesType:
+ // Camel properties
+ propertiesType :=
configMap.Labels["camel.apache.org/properties.type"]
+ resName := propertiesType + ".properties"
+
+ var mountPath string
+ switch propertiesType {
+ case "application":
+ mountPath =
filepath.Join(camel.BasePath, resName)
+ case "user":
+ mountPath =
filepath.Join(camel.ConfDPath, resName)
+ }
+
+ if propertiesType != "" {
+ refName := propertiesType +
"-properties"
+ vol := getVolume(refName, "configmap",
configMap.Name, "application.properties", resName)
+ mnt := getMount(refName, mountPath,
resName, true)
+
+ *vols = append(*vols, *vol)
+ *mnts = append(*mnts, *mnt)
+ } else {
+ log.WithValues("Function",
"trait.configureVolumesAndMounts").Infof("Warning: could not determine camel
properties type %s", propertiesType)
+ }
+ case KameletBundleType:
+ // Kamelets bundle configmap
+ kameletMountPoint :=
configMap.Annotations[kameletMountPointAnnotation]
+ refName := KameletBundleType
+ vol := getVolume(refName, "configmap",
configMap.Name, "", "")
+ mnt := getMount(refName, kameletMountPoint, "",
true)
+
+ *vols = append(*vols, *vol)
+ *mnts = append(*mnts, *mnt)
+ }
+ })
+ }
+}
+
+// mountResource add the resource to volumes and mounts and return the final
path where the resource is mounted.
+func (t *mountTrait) mountResource(vols *[]corev1.Volume, mnts
*[]corev1.VolumeMount, conf *utilResource.Config) string {
refName := kubernetes.SanitizeLabel(conf.Name())
dstDir := conf.DestinationPath()
dstFile := ""
@@ -180,6 +269,8 @@ func (t *mountTrait) mountResource(vols *[]corev1.Volume,
mnts *[]corev1.VolumeM
*vols = append(*vols, *vol)
*mnts = append(*mnts, *mnt)
+
+ return mnt.MountPath
}
func (t *mountTrait) addServiceBindingSecret(e *Environment) {
@@ -271,3 +362,77 @@ func createPVC(e *Environment, volumeParts []string) error
{
return nil
}
+
+// computeApplicationProperties is in charge to configure the configmap
containing Camel application.properties.
+func (t *mountTrait) computeApplicationProperties(e *Environment)
(*corev1.ConfigMap, error) {
+ // application properties
+ applicationProperties, err :=
property.EncodePropertyFile(e.ApplicationProperties)
+ if err != nil {
+ return nil, fmt.Errorf("could not compute application
properties: %w", err)
+ }
+
+ if applicationProperties != "" {
+ return &corev1.ConfigMap{
+ TypeMeta: metav1.TypeMeta{
+ Kind: "ConfigMap",
+ APIVersion: "v1",
+ },
+ ObjectMeta: metav1.ObjectMeta{
+ Name: e.Integration.Name +
"-application-properties",
+ Namespace: e.Integration.Namespace,
+ Labels: map[string]string{
+ v1.IntegrationLabel:
e.Integration.Name,
+ "camel.apache.org/properties.type":
"application",
+ kubernetes.ConfigMapTypeLabel:
CamelPropertiesType,
+ },
+ },
+ Data: map[string]string{
+ "application.properties": applicationProperties,
+ },
+ }, nil
+ }
+
+ return nil, nil
+}
+
+// addSourcesProperties is in charge to add the sources in the
application.properties required by Camel K Runtime.
+func (t *mountTrait) addSourcesProperties(e *Environment) {
+ if e.ApplicationProperties == nil {
+ e.ApplicationProperties = make(map[string]string)
+ }
+ idx := 0
+ for _, s := range e.Integration.AllSources() {
+ // We don't process routes embedded (native) or Kamelets
+ if e.isEmbedded(s) || s.IsGeneratedFromKamelet() {
+ continue
+ }
+ srcName := strings.TrimPrefix(filepath.ToSlash(s.Name), "/")
+ src := "file:" +
path.Join(filepath.ToSlash(camel.SourcesMountPath), srcName)
+
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].location", idx)] = src
+
+ simpleName := srcName
+ if strings.Contains(srcName, ".") {
+ simpleName = srcName[0:strings.Index(srcName, ".")]
+ }
+ e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].name",
idx)] = simpleName
+
+ for pid, p := range s.PropertyNames {
+
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].property-names[%d]",
idx, pid)] = p
+ }
+
+ if s.Type != "" {
+
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].type", idx)] =
string(s.Type)
+ }
+ if s.InferLanguage() != "" {
+
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].language", idx)] =
string(s.InferLanguage())
+ }
+ if s.Loader != "" {
+
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].loader", idx)] =
s.Loader
+ }
+ if s.Compression {
+
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].compressed", idx)] =
boolean.TrueString
+ }
+
+ idx++
+ }
+}
diff --git a/pkg/trait/mount_test.go b/pkg/trait/mount_test.go
index df551dbf5..701380193 100644
--- a/pkg/trait/mount_test.go
+++ b/pkg/trait/mount_test.go
@@ -31,6 +31,7 @@ import (
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
+ "github.com/apache/camel-k/v2/pkg/util/boolean"
"github.com/apache/camel-k/v2/pkg/util/camel"
"github.com/apache/camel-k/v2/pkg/util/gzip"
"github.com/apache/camel-k/v2/pkg/util/kubernetes"
@@ -341,3 +342,166 @@ func TestMountVolumesCreateUserStorageClass(t *testing.T)
{
assert.NoError(t, err)
assert.NotNil(t, pvc)
}
+
+func TestConfigureVolumesAndMountsSources(t *testing.T) {
+ trait, _ := newMountTrait().(*mountTrait)
+ env := Environment{
+ Resources: kubernetes.NewCollection(),
+ Integration: &v1.Integration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: TestDeploymentName,
+ Namespace: "ns",
+ },
+ Spec: v1.IntegrationSpec{
+ Sources: []v1.SourceSpec{
+ {
+ DataSpec: v1.DataSpec{
+ Name:
"source1.java",
+ ContentRef: "my-cm1",
+ ContentKey:
"source1.java",
+ },
+ Type: "data",
+ },
+ {
+ DataSpec: v1.DataSpec{
+ Name:
"source2.java",
+ ContentRef: "my-cm2",
+ },
+ Type: "data",
+ },
+ },
+ },
+ },
+ Catalog: &Catalog{},
+ }
+
+ vols := make([]corev1.Volume, 0)
+ mnts := make([]corev1.VolumeMount, 0)
+
+ trait.configureCamelVolumesAndMounts(&env, &vols, &mnts)
+
+ assert.Len(t, vols, 2)
+ assert.Len(t, mnts, 2)
+
+ v := findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm1" })
+ assert.NotNil(t, v)
+ assert.NotNil(t, v.VolumeSource.ConfigMap)
+ assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
+ assert.Equal(t, "source1.java", v.VolumeSource.ConfigMap.Items[0].Key)
+
+ m := findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
+ assert.NotNil(t, m)
+
+ v = findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm2" })
+ assert.NotNil(t, v)
+ assert.NotNil(t, v.VolumeSource.ConfigMap)
+ assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
+ assert.Equal(t, "content", v.VolumeSource.ConfigMap.Items[0].Key)
+
+ m = findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
+ assert.NotNil(t, m)
+}
+
+func TestConfigureVolumesAndMountsSourcesInNativeMode(t *testing.T) {
+ trait, _ := newMountTrait().(*mountTrait)
+ traitList := make([]Trait, 0, len(FactoryList))
+ quarkus, ok := newQuarkusTrait().(*quarkusTrait)
+ assert.True(t, ok, "A Quarkus trait was expected")
+ quarkus.Modes = []traitv1.QuarkusMode{traitv1.NativeQuarkusMode}
+ traitList = append(traitList, quarkus)
+ env := Environment{
+ Resources: kubernetes.NewCollection(),
+ Integration: &v1.Integration{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: TestDeploymentName,
+ Namespace: "ns",
+ },
+ Spec: v1.IntegrationSpec{
+ Sources: []v1.SourceSpec{
+ {
+ DataSpec: v1.DataSpec{
+ Name:
"source1.xml",
+ ContentRef: "my-cm1",
+ ContentKey:
"source1.xml",
+ },
+ Type: "data",
+ },
+ {
+ DataSpec: v1.DataSpec{
+ Name:
"source2.java",
+ ContentRef: "my-cm2",
+ },
+ Type: "data",
+ },
+ {
+ DataSpec: v1.DataSpec{
+ Name:
"source1.java",
+ ContentRef: "my-cm3",
+ ContentKey:
"source1.java",
+ },
+ Type: "data",
+ },
+ {
+ DataSpec: v1.DataSpec{
+ Name:
"source2.xml",
+ ContentRef: "my-cm4",
+ },
+ Type: "data",
+ },
+ },
+ },
+ Status: v1.IntegrationStatus{
+ Phase: v1.IntegrationPhaseRunning,
+ },
+ },
+ IntegrationKit: &v1.IntegrationKit{
+ ObjectMeta: metav1.ObjectMeta{
+ Labels: map[string]string{
+ v1.IntegrationKitLayoutLabel:
v1.IntegrationKitLayoutNativeSources,
+ },
+ Namespace: "ns",
+ },
+ },
+ Catalog: &Catalog{
+ traits: traitList,
+ },
+ CamelCatalog: &camel.RuntimeCatalog{
+ CamelCatalogSpec: v1.CamelCatalogSpec{
+ Loaders: map[string]v1.CamelLoader{
+ "java": {
+ Metadata: map[string]string{
+ "native":
boolean.TrueString,
+
"sources-required-at-build-time": boolean.TrueString,
+ },
+ },
+ },
+ },
+ },
+ }
+
+ vols := make([]corev1.Volume, 0)
+ mnts := make([]corev1.VolumeMount, 0)
+
+ trait.configureCamelVolumesAndMounts(&env, &vols, &mnts)
+
+ assert.Len(t, vols, 2)
+ assert.Len(t, mnts, 2)
+
+ v := findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm1" })
+ assert.NotNil(t, v)
+ assert.NotNil(t, v.VolumeSource.ConfigMap)
+ assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
+ assert.Equal(t, "source1.xml", v.VolumeSource.ConfigMap.Items[0].Key)
+
+ m := findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
+ assert.NotNil(t, m)
+
+ v = findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm4" })
+ assert.NotNil(t, v)
+ assert.NotNil(t, v.VolumeSource.ConfigMap)
+ assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
+ assert.Equal(t, "content", v.VolumeSource.ConfigMap.Items[0].Key)
+
+ m = findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
+ assert.NotNil(t, m)
+}
diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go
index 105e4eace..2324dd8cf 100644
--- a/pkg/trait/trait_test.go
+++ b/pkg/trait/trait_test.go
@@ -36,7 +36,6 @@ import (
v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
traitv1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1/trait"
"github.com/apache/camel-k/v2/pkg/resources"
- "github.com/apache/camel-k/v2/pkg/util/boolean"
"github.com/apache/camel-k/v2/pkg/util/camel"
"github.com/apache/camel-k/v2/pkg/util/defaults"
"github.com/apache/camel-k/v2/pkg/util/kubernetes"
@@ -56,9 +55,6 @@ func TestOpenShiftTraits(t *testing.T) {
assert.Nil(t, env.GetTrait("service"))
assert.Nil(t, env.GetTrait("route"))
assert.NotNil(t, env.GetTrait("owner"))
- assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
- return cm.Labels["camel.apache.org/properties.type"] != ""
- }))
assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment)
bool {
return deployment.Name == TestDeploymentName
}))
@@ -71,9 +67,6 @@ func TestOpenShiftTraitsWithWeb(t *testing.T) {
assert.NotNil(t, env.GetTrait("service"))
assert.NotNil(t, env.GetTrait("route"))
assert.NotNil(t, env.GetTrait("owner"))
- assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
- return cm.Labels["camel.apache.org/properties.type"] != ""
- }))
assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment)
bool {
return deployment.Name == TestDeploymentName
}))
@@ -117,9 +110,6 @@ func TestKubernetesTraits(t *testing.T) {
assert.Nil(t, env.GetTrait("service"))
assert.Nil(t, env.GetTrait("route"))
assert.NotNil(t, env.GetTrait("owner"))
- assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
- return cm.Labels["camel.apache.org/properties.type"] != ""
- }))
assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment)
bool {
return deployment.Name == TestDeploymentName
}))
@@ -132,9 +122,6 @@ func TestKubernetesTraitsWithWeb(t *testing.T) {
assert.NotNil(t, env.GetTrait("service"))
assert.Nil(t, env.GetTrait("route"))
assert.NotNil(t, env.GetTrait("owner"))
- assert.NotNil(t, res.GetConfigMap(func(cm *corev1.ConfigMap) bool {
- return cm.Labels["camel.apache.org/properties.type"] != ""
- }))
assert.NotNil(t, res.GetDeployment(func(deployment *appsv1.Deployment)
bool {
return deployment.Name == TestDeploymentName
}))
@@ -189,167 +176,6 @@ func TestTraitHierarchyDecode(t *testing.T) {
assert.Equal(t, 15, *kns.Target)
}
-func TestConfigureVolumesAndMountsSources(t *testing.T) {
- env := Environment{
- Resources: kubernetes.NewCollection(),
- Integration: &v1.Integration{
- ObjectMeta: metav1.ObjectMeta{
- Name: TestDeploymentName,
- Namespace: "ns",
- },
- Spec: v1.IntegrationSpec{
- Sources: []v1.SourceSpec{
- {
- DataSpec: v1.DataSpec{
- Name:
"source1.java",
- ContentRef: "my-cm1",
- ContentKey:
"source1.java",
- },
- Type: "data",
- },
- {
- DataSpec: v1.DataSpec{
- Name:
"source2.java",
- ContentRef: "my-cm2",
- },
- Type: "data",
- },
- },
- },
- },
- Catalog: &Catalog{},
- }
-
- vols := make([]corev1.Volume, 0)
- mnts := make([]corev1.VolumeMount, 0)
-
- env.configureVolumesAndMounts(&vols, &mnts)
-
- assert.Len(t, vols, 2)
- assert.Len(t, mnts, 2)
-
- v := findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm1" })
- assert.NotNil(t, v)
- assert.NotNil(t, v.VolumeSource.ConfigMap)
- assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
- assert.Equal(t, "source1.java", v.VolumeSource.ConfigMap.Items[0].Key)
-
- m := findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
- assert.NotNil(t, m)
-
- v = findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm2" })
- assert.NotNil(t, v)
- assert.NotNil(t, v.VolumeSource.ConfigMap)
- assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
- assert.Equal(t, "content", v.VolumeSource.ConfigMap.Items[0].Key)
-
- m = findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
- assert.NotNil(t, m)
-}
-
-func TestConfigureVolumesAndMountsSourcesInNativeMode(t *testing.T) {
- traitList := make([]Trait, 0, len(FactoryList))
- trait, ok := newQuarkusTrait().(*quarkusTrait)
- assert.True(t, ok, "A Quarkus trait was expected")
- trait.Modes = []traitv1.QuarkusMode{traitv1.NativeQuarkusMode}
- traitList = append(traitList, trait)
- env := Environment{
- Resources: kubernetes.NewCollection(),
- Integration: &v1.Integration{
- ObjectMeta: metav1.ObjectMeta{
- Name: TestDeploymentName,
- Namespace: "ns",
- },
- Spec: v1.IntegrationSpec{
- Sources: []v1.SourceSpec{
- {
- DataSpec: v1.DataSpec{
- Name:
"source1.xml",
- ContentRef: "my-cm1",
- ContentKey:
"source1.xml",
- },
- Type: "data",
- },
- {
- DataSpec: v1.DataSpec{
- Name:
"source2.java",
- ContentRef: "my-cm2",
- },
- Type: "data",
- },
- {
- DataSpec: v1.DataSpec{
- Name:
"source1.java",
- ContentRef: "my-cm3",
- ContentKey:
"source1.java",
- },
- Type: "data",
- },
- {
- DataSpec: v1.DataSpec{
- Name:
"source2.xml",
- ContentRef: "my-cm4",
- },
- Type: "data",
- },
- },
- },
- Status: v1.IntegrationStatus{
- Phase: v1.IntegrationPhaseRunning,
- },
- },
- IntegrationKit: &v1.IntegrationKit{
- ObjectMeta: metav1.ObjectMeta{
- Labels: map[string]string{
- v1.IntegrationKitLayoutLabel:
v1.IntegrationKitLayoutNativeSources,
- },
- Namespace: "ns",
- },
- },
- Catalog: &Catalog{
- traits: traitList,
- },
- CamelCatalog: &camel.RuntimeCatalog{
- CamelCatalogSpec: v1.CamelCatalogSpec{
- Loaders: map[string]v1.CamelLoader{
- "java": {
- Metadata: map[string]string{
- "native":
boolean.TrueString,
-
"sources-required-at-build-time": boolean.TrueString,
- },
- },
- },
- },
- },
- }
-
- vols := make([]corev1.Volume, 0)
- mnts := make([]corev1.VolumeMount, 0)
-
- env.configureVolumesAndMounts(&vols, &mnts)
-
- assert.Len(t, vols, 2)
- assert.Len(t, mnts, 2)
-
- v := findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm1" })
- assert.NotNil(t, v)
- assert.NotNil(t, v.VolumeSource.ConfigMap)
- assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
- assert.Equal(t, "source1.xml", v.VolumeSource.ConfigMap.Items[0].Key)
-
- m := findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
- assert.NotNil(t, m)
-
- v = findVolume(vols, func(v corev1.Volume) bool { return
v.ConfigMap.Name == "my-cm4" })
- assert.NotNil(t, v)
- assert.NotNil(t, v.VolumeSource.ConfigMap)
- assert.Len(t, v.VolumeSource.ConfigMap.Items, 1)
- assert.Equal(t, "content", v.VolumeSource.ConfigMap.Items[0].Key)
-
- m = findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return
m.Name == v.Name })
- assert.NotNil(t, m)
-}
-
func TestOnlySomeTraitsInfluenceBuild(t *testing.T) {
c := NewTraitTestCatalog()
buildTraits := []string{"builder", "camel", "quarkus", "registry"}
diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go
index 2daff6631..edb3bb271 100644
--- a/pkg/trait/trait_types.go
+++ b/pkg/trait/trait_types.go
@@ -20,7 +20,6 @@ package trait
import (
"context"
"fmt"
- "path"
"path/filepath"
"regexp"
"sort"
@@ -30,7 +29,6 @@ import (
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
serving "knative.dev/serving/pkg/apis/serving/v1"
@@ -38,11 +36,9 @@ import (
"github.com/apache/camel-k/v2/pkg/client"
"github.com/apache/camel-k/v2/pkg/metadata"
"github.com/apache/camel-k/v2/pkg/platform"
- "github.com/apache/camel-k/v2/pkg/util/boolean"
"github.com/apache/camel-k/v2/pkg/util/camel"
"github.com/apache/camel-k/v2/pkg/util/kubernetes"
"github.com/apache/camel-k/v2/pkg/util/log"
- "github.com/apache/camel-k/v2/pkg/util/property"
)
const (
@@ -421,146 +417,6 @@ func (e *Environment) DetermineCatalogNamespace() string {
return ""
}
-func (e *Environment) computeApplicationProperties() (*corev1.ConfigMap,
error) {
- // application properties
- applicationProperties, err :=
property.EncodePropertyFile(e.ApplicationProperties)
- if err != nil {
- return nil, fmt.Errorf("could not compute application
properties: %w", err)
- }
-
- if applicationProperties != "" {
- return &corev1.ConfigMap{
- TypeMeta: metav1.TypeMeta{
- Kind: "ConfigMap",
- APIVersion: "v1",
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: e.Integration.Name +
"-application-properties",
- Namespace: e.Integration.Namespace,
- Labels: map[string]string{
- v1.IntegrationLabel:
e.Integration.Name,
- "camel.apache.org/properties.type":
"application",
- kubernetes.ConfigMapTypeLabel:
CamelPropertiesType,
- },
- },
- Data: map[string]string{
- "application.properties": applicationProperties,
- },
- }, nil
- }
-
- return nil, nil
-}
-
-func (e *Environment) addSourcesProperties() {
- if e.ApplicationProperties == nil {
- e.ApplicationProperties = make(map[string]string)
- }
- idx := 0
- for _, s := range e.Integration.AllSources() {
- // We don't process routes embedded (native) or Kamelets
- if e.isEmbedded(s) || s.IsGeneratedFromKamelet() {
- continue
- }
- srcName := strings.TrimPrefix(filepath.ToSlash(s.Name), "/")
- src := "file:" +
path.Join(filepath.ToSlash(camel.SourcesMountPath), srcName)
-
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].location", idx)] = src
-
- simpleName := srcName
- if strings.Contains(srcName, ".") {
- simpleName = srcName[0:strings.Index(srcName, ".")]
- }
- e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].name",
idx)] = simpleName
-
- for pid, p := range s.PropertyNames {
-
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].property-names[%d]",
idx, pid)] = p
- }
-
- if s.Type != "" {
-
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].type", idx)] =
string(s.Type)
- }
- if s.InferLanguage() != "" {
-
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].language", idx)] =
string(s.InferLanguage())
- }
- if s.Loader != "" {
-
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].loader", idx)] =
s.Loader
- }
- if s.Compression {
-
e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].compressed", idx)] =
boolean.TrueString
- }
-
- idx++
- }
-}
-
-func (e *Environment) configureVolumesAndMounts(vols *[]corev1.Volume, mnts
*[]corev1.VolumeMount) {
- // Sources
- idx := 0
- for _, s := range e.Integration.AllSources() {
- // We don't process routes embedded (native) or Kamelets
- if e.isEmbedded(s) || s.IsGeneratedFromKamelet() {
- continue
- }
- // Routes are copied under /etc/camel/sources and discovered by
the runtime accordingly
- cmName := fmt.Sprintf("%s-source-%03d", e.Integration.Name, idx)
- if s.ContentRef != "" {
- cmName = s.ContentRef
- }
- cmKey := "content"
- if s.ContentKey != "" {
- cmKey = s.ContentKey
- }
- resName := strings.TrimPrefix(s.Name, "/")
- refName := fmt.Sprintf("i-source-%03d", idx)
- resPath := filepath.Join(camel.SourcesMountPath, resName)
- vol := getVolume(refName, "configmap", cmName, cmKey, resName)
- mnt := getMount(refName, resPath, resName, true)
-
- *vols = append(*vols, *vol)
- *mnts = append(*mnts, *mnt)
- idx++
- }
- // Resources (likely application properties or kamelets)
- if e.Resources != nil {
- e.Resources.VisitConfigMap(func(configMap *corev1.ConfigMap) {
- switch configMap.Labels[kubernetes.ConfigMapTypeLabel] {
- case CamelPropertiesType:
- // Camel properties
- propertiesType :=
configMap.Labels["camel.apache.org/properties.type"]
- resName := propertiesType + ".properties"
-
- var mountPath string
- switch propertiesType {
- case "application":
- mountPath =
filepath.Join(camel.BasePath, resName)
- case "user":
- mountPath =
filepath.Join(camel.ConfDPath, resName)
- }
-
- if propertiesType != "" {
- refName := propertiesType +
"-properties"
- vol := getVolume(refName, "configmap",
configMap.Name, "application.properties", resName)
- mnt := getMount(refName, mountPath,
resName, true)
-
- *vols = append(*vols, *vol)
- *mnts = append(*mnts, *mnt)
- } else {
- log.WithValues("Function",
"trait.configureVolumesAndMounts").Infof("Warning: could not determine camel
properties type %s", propertiesType)
- }
- case KameletBundleType:
- // Kamelets bundle configmap
- kameletMountPoint :=
configMap.Annotations[kameletMountPointAnnotation]
- refName := KameletBundleType
- vol := getVolume(refName, "configmap",
configMap.Name, "", "")
- mnt := getMount(refName, kameletMountPoint, "",
true)
-
- *vols = append(*vols, *vol)
- *mnts = append(*mnts, *mnt)
- }
- })
- }
-}
-
func getVolume(volName, storageType, storageName, filterKey, filterValue
string) *corev1.Volume {
items := convertToKeyToPath(filterKey, filterValue)
volume := corev1.Volume{
@@ -782,3 +638,11 @@ func (e *Environment) consumeSourcesMeta(
return consumeMeta(meta), nil
}
+
+func (e *Environment) appendCloudPropertiesLocation(cloudPropertiesLocation
string) {
+ if e.ApplicationProperties["camel.main.cloud-properties-location"] ==
"" {
+ e.ApplicationProperties["camel.main.cloud-properties-location"]
= cloudPropertiesLocation
+ } else {
+ e.ApplicationProperties["camel.main.cloud-properties-location"]
+= "," + cloudPropertiesLocation
+ }
+}
diff --git a/pkg/trait/trait_types_test.go b/pkg/trait/trait_types_test.go
index 608fc3d07..e08221432 100644
--- a/pkg/trait/trait_types_test.go
+++ b/pkg/trait/trait_types_test.go
@@ -34,19 +34,6 @@ import (
"github.com/apache/camel-k/v2/pkg/util/test"
)
-func TestMultilinePropertiesHandled(t *testing.T) {
- e := Environment{
- ApplicationProperties: map[string]string{
- "prop": "multi\nline",
- },
- Integration: &v1.Integration{},
- }
- cm, err := e.computeApplicationProperties()
- require.NoError(t, err)
- assert.NotNil(t, cm)
- assert.Equal(t, "prop = multi\\nline\n",
cm.Data["application.properties"])
-}
-
func TestCollectConfigurationValues(t *testing.T) {
e := Environment{
Integration: &v1.Integration{
diff --git a/pkg/util/kubernetes/lookup.go b/pkg/util/kubernetes/lookup.go
index 2ce961d5b..3fb2d0256 100644
--- a/pkg/util/kubernetes/lookup.go
+++ b/pkg/util/kubernetes/lookup.go
@@ -29,6 +29,7 @@ import (
)
// LookupConfigmap will look for any k8s Configmap with a given name in a
given namespace.
+// Deprecated: won't be supported in future releases.
func LookupConfigmap(ctx context.Context, c client.Client, ns string, name
string) *corev1.ConfigMap {
cm := corev1.ConfigMap{
TypeMeta: metav1.TypeMeta{
@@ -62,6 +63,7 @@ func LookupResourceVersion(ctx context.Context, c
client.Client, object ctrl.Obj
}
// LookupSecret will look for any k8s Secret with a given name in a given
namespace.
+// Deprecated: won't be supported in future releases.
func LookupSecret(ctx context.Context, c client.Client, ns string, name
string) *corev1.Secret {
secret := corev1.Secret{
TypeMeta: metav1.TypeMeta{