diff --git a/examples/user-config/resource-file-base64-encoded-route.groovy b/examples/user-config/resource-file-base64-encoded-route.groovy index 281d6ad350..b88244da6a 100644 --- a/examples/user-config/resource-file-base64-encoded-route.groovy +++ b/examples/user-config/resource-file-base64-encoded-route.groovy @@ -18,7 +18,7 @@ // // To run this integrations use: -// kamel run --resource resources-data.txt --compression=true resource-file-base64-encoded-route.groovy --dev +// kamel run --resource file:resources-data.txt --compression=true resource-file-base64-encoded-route.groovy --dev // from('timer:resources-bas64') diff --git a/examples/user-config/resource-file-binary-route.groovy b/examples/user-config/resource-file-binary-route.groovy index eef04d1336..7f88b9ab5b 100644 --- a/examples/user-config/resource-file-binary-route.groovy +++ b/examples/user-config/resource-file-binary-route.groovy @@ -18,7 +18,7 @@ // // To run this integrations use: -// kamel run --resource resources-data.zip resource-file-binary-route.groovy -d camel-zipfile --dev +// kamel run --resource file:resources-data.zip resource-file-binary-route.groovy -d camel-zipfile --dev // from('file:/etc/camel/resources/?fileName=resources-data.zip&noop=true&idempotent=false') diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go index 153c13c31f..767dadad1e 100644 --- a/pkg/cmd/run.go +++ b/pkg/cmd/run.go @@ -568,10 +568,26 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C return nil, err } + generatedConfigmaps := make([]*corev1.ConfigMap, 0) + for _, resource := range o.Resources { if config, parseErr := ParseResourceOption(resource); parseErr == nil { - if applyResourceOptionErr := ApplyResourceOption(o.Context, config, &integration.Spec, c, namespace, o.Compression); applyResourceOptionErr != nil { + if genCm, applyResourceOptionErr := ApplyResourceOption(o.Context, config, integration, c, namespace, o.Compression); applyResourceOptionErr != nil { return nil, applyResourceOptionErr + } else if genCm != nil { + generatedConfigmaps = append(generatedConfigmaps, genCm) + } + } else { + return nil, parseErr + } + } + + for _, item := range o.Configs { + if config, parseErr := ParseConfigOption(item); parseErr == nil { + if genCm, applyConfigOptionErr := ApplyConfigOption(o.Context, config, integration, c, namespace, o.Compression); applyConfigOptionErr != nil { + return nil, applyConfigOptionErr + } else if genCm != nil { + generatedConfigmaps = append(generatedConfigmaps, genCm) } } else { return nil, parseErr @@ -619,15 +635,6 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C o.Traits = append(o.Traits, buildPropsTraits...) } - for _, item := range o.Configs { - if config, parseErr := ParseConfigOption(item); parseErr == nil { - if applyConfigOptionErr := ApplyConfigOption(o.Context, config, &integration.Spec, c, namespace, o.Compression); applyConfigOptionErr != nil { - return nil, applyConfigOptionErr - } - } else { - return nil, parseErr - } - } for _, item := range o.ConfigMaps { integration.Spec.AddConfiguration("configmap", item) } @@ -670,18 +677,21 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C if existing == nil { err = c.Create(o.Context, integration) + fmt.Printf("Integration \"%s\" created\n", name) } else { err = c.Patch(o.Context, integration, ctrl.MergeFromWithOptions(existing, ctrl.MergeFromWithOptimisticLock{})) + fmt.Printf("Integration \"%s\" updated\n", name) } if err != nil { return nil, err } - if existing == nil { - fmt.Printf("Integration \"%s\" created\n", name) - } else { - fmt.Printf("Integration \"%s\" updated\n", name) + if generatedConfigmaps != nil { + err = bindGeneratedConfigmapsToIntegration(o.Context, c, integration, generatedConfigmaps) + if err != nil { + return integration, err + } } return integration, nil } diff --git a/pkg/cmd/run_help.go b/pkg/cmd/run_help.go index 5104ac90b7..5ccbe146c8 100644 --- a/pkg/cmd/run_help.go +++ b/pkg/cmd/run_help.go @@ -19,15 +19,21 @@ package cmd import ( "context" + "crypto/sha1" "fmt" "path" + "path/filepath" "regexp" "strings" v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/client" + "github.com/apache/camel-k/pkg/util/camel" "github.com/apache/camel-k/pkg/util/kubernetes" "github.com/magiconair/properties" + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var invalidPaths = []string{"/etc/camel", "/deployments/dependencies"} @@ -181,8 +187,9 @@ func parseOption(item string) (*RunConfigOption, error) { return configurationOption, nil } -func applyOption(ctx context.Context, config *RunConfigOption, integrationSpec *v1.IntegrationSpec, - c client.Client, namespace string, enableCompression bool, resourceType v1.ResourceType) error { +func applyOption(ctx context.Context, config *RunConfigOption, integration *v1.Integration, + c client.Client, namespace string, enableCompression bool, resourceType v1.ResourceType) (*corev1.ConfigMap, error) { + var maybeGenCm *corev1.ConfigMap switch config.configType { case ConfigOptionTypeConfigmap: cm := kubernetes.LookupConfigmap(ctx, c, namespace, config.Name()) @@ -190,58 +197,97 @@ func applyOption(ctx context.Context, config *RunConfigOption, integrationSpec * fmt.Printf("Warn: %s Configmap not found in %s namespace, make sure to provide it before the Integration can run\n", config.Name(), namespace) } else if resourceType != v1.ResourceTypeData && cm.BinaryData != nil { - return fmt.Errorf("you cannot provide a binary config, use a text file instead") + return maybeGenCm, fmt.Errorf("you cannot provide a binary config, use a text file instead") } - integrationSpec.AddConfigurationAsResource(config.Type(), config.Name(), string(resourceType), config.DestinationPath(), config.Key()) case ConfigOptionTypeSecret: secret := kubernetes.LookupSecret(ctx, c, namespace, config.Name()) 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.Name(), namespace) } - integrationSpec.AddConfigurationAsResource(string(config.configType), config.Name(), string(resourceType), config.DestinationPath(), config.Key()) case ConfigOptionTypeFile: - // Don't allow a file size longer than 1 MiB - fileSize, err := fileSize(config.Name()) - printSize := fmt.Sprintf("%.2f", float64(fileSize)/Megabyte) - if err != nil { - return err - } else if fileSize > Megabyte { - return fmt.Errorf("you cannot provide a file larger than 1 MB (it was %s MB), check configmap option or --volume instead", printSize) - } // Don't allow a binary non compressed resource rawData, contentType, err := loadRawContent(ctx, config.Name()) if err != nil { - return err + return maybeGenCm, err } if resourceType != v1.ResourceTypeData && !enableCompression && isBinary(contentType) { - return fmt.Errorf("you cannot provide a binary config, use a text file or check --resource flag instead") + return maybeGenCm, fmt.Errorf("you cannot provide a binary config, use a text file or check --resource flag instead") } resourceSpec, err := binaryOrTextResource(path.Base(config.Name()), rawData, contentType, enableCompression, resourceType, config.DestinationPath()) if err != nil { - return err + return maybeGenCm, err + } + maybeGenCm, err = convertFileToConfigmap(ctx, c, resourceSpec, config, integration.Namespace, resourceType) + if err != nil { + return maybeGenCm, err } - integrationSpec.AddResources(resourceSpec) default: // Should never reach this - return fmt.Errorf("invalid option type %s", config.configType) + return maybeGenCm, fmt.Errorf("invalid option type %s", config.configType) } - return nil + integration.Spec.AddConfigurationAsResource(config.Type(), config.Name(), string(resourceType), config.DestinationPath(), config.Key()) + + return maybeGenCm, nil } -// ApplyConfigOption will set the proper --config option behavior to the IntegrationSpec. -func ApplyConfigOption(ctx context.Context, config *RunConfigOption, integrationSpec *v1.IntegrationSpec, c client.Client, namespace string, enableCompression bool) error { +func convertFileToConfigmap(ctx context.Context, c client.Client, resourceSpec v1.ResourceSpec, config *RunConfigOption, + namespace string, resourceType v1.ResourceType) (*corev1.ConfigMap, error) { + if config.DestinationPath() == "" { + config.resourceKey = filepath.Base(config.Name()) + // As we are changing the resource to a configmap type + // we need to declare the mount path not to use the + // default behavior of a configmap (which include a subdirectory with the configmap name) + if resourceType == v1.ResourceTypeData { + config.destinationPath = camel.ResourcesDefaultMountPath + } else { + config.destinationPath = camel.ConfigResourcesMountPath + } + } else { + config.resourceKey = filepath.Base(config.DestinationPath()) + config.destinationPath = filepath.Dir(config.DestinationPath()) + } + genCmName := fmt.Sprintf("cm-%s", hashFrom([]byte(resourceSpec.Content), resourceSpec.RawContent)) + cm := kubernetes.NewConfigmap(namespace, genCmName, config.Name(), config.Key(), resourceSpec.Content, resourceSpec.RawContent) + err := c.Create(ctx, cm) + if err != nil { + if k8serrors.IsAlreadyExists(err) { + // We'll reuse it, as is + } else { + return cm, err + } + } + config.configType = ConfigOptionTypeConfigmap + config.resourceName = cm.Name + + return cm, nil +} + +func hashFrom(contents ...[]byte) string { + // SHA1 because we need to limit the lenght to less than 64 chars + hash := sha1.New() + for _, c := range contents { + hash.Write(c) + } + + return fmt.Sprintf("%x", hash.Sum(nil)) +} + +// ApplyConfigOption will set the proper --config option behavior to the IntegrationSpec +func ApplyConfigOption(ctx context.Context, config *RunConfigOption, integration *v1.Integration, c client.Client, + namespace string, enableCompression bool) (*corev1.ConfigMap, error) { // A config option cannot specify destination path if config.DestinationPath() != "" { - return fmt.Errorf("cannot specify a destination path for this option type") + return nil, fmt.Errorf("cannot specify a destination path for this option type") } - return applyOption(ctx, config, integrationSpec, c, namespace, enableCompression, v1.ResourceTypeConfig) + return applyOption(ctx, config, integration, c, namespace, enableCompression, v1.ResourceTypeConfig) } -// ApplyResourceOption will set the proper --resource option behavior to the IntegrationSpec. -func ApplyResourceOption(ctx context.Context, config *RunConfigOption, integrationSpec *v1.IntegrationSpec, c client.Client, namespace string, enableCompression bool) error { - return applyOption(ctx, config, integrationSpec, c, namespace, enableCompression, v1.ResourceTypeData) +// ApplyResourceOption will set the proper --resource option behavior to the IntegrationSpec +func ApplyResourceOption(ctx context.Context, config *RunConfigOption, integration *v1.Integration, c client.Client, + namespace string, enableCompression bool) (*corev1.ConfigMap, error) { + return applyOption(ctx, config, integration, c, namespace, enableCompression, v1.ResourceTypeData) } func binaryOrTextResource(fileName string, data []byte, contentType string, base64Compression bool, resourceType v1.ResourceType, destinationPath string) (v1.ResourceSpec, error) { @@ -319,3 +365,29 @@ func extractProperties(value string) (*properties.Properties, error) { func keyValueProps(value string) (*properties.Properties, error) { return properties.Load([]byte(value), properties.UTF8) } + +func bindGeneratedConfigmapsToIntegration(ctx context.Context, c client.Client, i *v1.Integration, configmaps []*corev1.ConfigMap) error { + controller := true + blockOwnerDeletion := true + for _, cm := range configmaps { + cm.ObjectMeta.Labels[v1.IntegrationLabel] = i.Name + cm.ObjectMeta.Labels["camel.apache.org/autogenerated"] = "true" + // set owner references + cm.ObjectMeta.OwnerReferences = []metav1.OwnerReference{ + { + Kind: v1.IntegrationKind, + APIVersion: v1.SchemeGroupVersion.String(), + Name: i.Name, + UID: i.UID, + Controller: &controller, + BlockOwnerDeletion: &blockOwnerDeletion, + }, + } + err := c.Update(ctx, cm) + if err != nil { + return err + } + } + + return nil +} diff --git a/pkg/trait/container.go b/pkg/trait/container.go index d9eae9e87d..7e67ae715a 100644 --- a/pkg/trait/container.go +++ b/pkg/trait/container.go @@ -31,6 +31,7 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/util" + "github.com/apache/camel-k/pkg/util/camel" "github.com/apache/camel-k/pkg/util/defaults" "github.com/apache/camel-k/pkg/util/envvar" "github.com/apache/camel-k/pkg/util/kubernetes" @@ -245,8 +246,8 @@ func (t *containerTrait) configureContainer(e *Environment) error { } envvar.SetVal(&container.Env, "CAMEL_K_DIGEST", e.Integration.Status.Digest) - envvar.SetVal(&container.Env, "CAMEL_K_CONF", path.Join(basePath, "application.properties")) - envvar.SetVal(&container.Env, "CAMEL_K_CONF_D", confDPath) + envvar.SetVal(&container.Env, "CAMEL_K_CONF", path.Join(camel.BasePath, "application.properties")) + envvar.SetVal(&container.Env, "CAMEL_K_CONF_D", camel.ConfDPath) e.addSourcesProperties() diff --git a/pkg/trait/environment.go b/pkg/trait/environment.go index 3f96d24f37..2a21580944 100644 --- a/pkg/trait/environment.go +++ b/pkg/trait/environment.go @@ -18,6 +18,7 @@ limitations under the License. package trait import ( + "github.com/apache/camel-k/pkg/util/camel" "github.com/apache/camel-k/pkg/util/defaults" "github.com/apache/camel-k/pkg/util/envvar" "github.com/apache/camel-k/pkg/util/property" @@ -73,8 +74,8 @@ func (t *environmentTrait) Apply(e *Environment) error { envvar.SetVal(&e.EnvVars, envVarCamelKIntegration, e.Integration.Name) } envvar.SetVal(&e.EnvVars, envVarCamelKRuntimeVersion, e.RuntimeVersion) - envvar.SetVal(&e.EnvVars, envVarMountPathConfigMaps, configConfigmapsMountPath) - envvar.SetVal(&e.EnvVars, envVarMountPathSecrets, configSecretsMountPath) + envvar.SetVal(&e.EnvVars, envVarMountPathConfigMaps, camel.ConfigConfigmapsMountPath) + envvar.SetVal(&e.EnvVars, envVarMountPathSecrets, camel.ConfigSecretsMountPath) if IsNilOrTrue(t.ContainerMeta) { envvar.SetValFrom(&e.EnvVars, envVarNamespace, "metadata.namespace") diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go index 4787ca345a..994a53241d 100644 --- a/pkg/trait/jvm.go +++ b/pkg/trait/jvm.go @@ -37,6 +37,7 @@ import ( v1 "github.com/apache/camel-k/pkg/apis/camel/v1" "github.com/apache/camel-k/pkg/builder" "github.com/apache/camel-k/pkg/util" + "github.com/apache/camel-k/pkg/util/camel" ) // The JVM trait is used to configure the JVM that runs the integration. @@ -108,8 +109,8 @@ func (t *jvmTrait) Apply(e *Environment) error { classpath := strset.New() classpath.Add("./resources") - classpath.Add(configResourcesMountPath) - classpath.Add(resourcesDefaultMountPath) + classpath.Add(camel.ConfigResourcesMountPath) + classpath.Add(camel.ResourcesDefaultMountPath) if t.Classpath != "" { classpath.Add(strings.Split(t.Classpath, ":")...) } diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go index 4360692e59..760dadf97e 100644 --- a/pkg/trait/jvm_test.go +++ b/pkg/trait/jvm_test.go @@ -102,12 +102,12 @@ func TestApplyJvmTraitWithDeploymentResource(t *testing.T) { assert.Nil(t, err) - cp := strset.New("./resources", configResourcesMountPath, resourcesDefaultMountPath, "/mount/path").List() + cp := strset.New("./resources", camel.ConfigResourcesMountPath, camel.ResourcesDefaultMountPath, "/mount/path").List() sort.Strings(cp) assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s:/mount/path", configResourcesMountPath, resourcesDefaultMountPath), + fmt.Sprintf("./resources:%s:%s:/mount/path", camel.ConfigResourcesMountPath, camel.ResourcesDefaultMountPath), "io.quarkus.bootstrap.runner.QuarkusEntryPoint", }, d.Spec.Template.Spec.Containers[0].Args) } @@ -134,12 +134,12 @@ func TestApplyJvmTraitWithKNativeResource(t *testing.T) { assert.Nil(t, err) - cp := strset.New("./resources", configResourcesMountPath, resourcesDefaultMountPath, "/mount/path").List() + cp := strset.New("./resources", camel.ConfigResourcesMountPath, camel.ResourcesDefaultMountPath, "/mount/path").List() sort.Strings(cp) assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s:/mount/path", configResourcesMountPath, resourcesDefaultMountPath), + fmt.Sprintf("./resources:%s:%s:/mount/path", camel.ConfigResourcesMountPath, camel.ResourcesDefaultMountPath), "io.quarkus.bootstrap.runner.QuarkusEntryPoint", }, s.Spec.Template.Spec.Containers[0].Args) } @@ -243,7 +243,7 @@ func TestApplyJvmTraitWithClasspath(t *testing.T) { assert.Nil(t, err) assert.Equal(t, []string{ "-cp", - fmt.Sprintf("./resources:%s:%s:/mount/path:%s:%s", configResourcesMountPath, resourcesDefaultMountPath, + fmt.Sprintf("./resources:%s:%s:/mount/path:%s:%s", camel.ConfigResourcesMountPath, camel.ResourcesDefaultMountPath, "/path/to/another/dep.jar", "/path/to/my-dep.jar"), "io.quarkus.bootstrap.runner.QuarkusEntryPoint", }, d.Spec.Template.Spec.Containers[0].Args) diff --git a/pkg/trait/service_binding.go b/pkg/trait/service_binding.go index 1b574f7386..ab7a78a3dd 100644 --- a/pkg/trait/service_binding.go +++ b/pkg/trait/service_binding.go @@ -18,6 +18,7 @@ limitations under the License. package trait import ( + "github.com/apache/camel-k/pkg/util/camel" "github.com/apache/camel-k/pkg/util/reference" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -77,7 +78,7 @@ func (t *serviceBindingTrait) Apply(e *Environment) error { if secret != nil { e.Resources.Add(secret) e.ApplicationProperties["quarkus.kubernetes-service-binding.enabled"] = "true" - e.ApplicationProperties["SERVICE_BINDING_ROOT"] = serviceBindingsMountPath + e.ApplicationProperties["SERVICE_BINDING_ROOT"] = camel.ServiceBindingsMountPath e.ServiceBindingSecret = secret.GetName() } return nil diff --git a/pkg/trait/trait_test.go b/pkg/trait/trait_test.go index 0f1f5d8a80..bef6932721 100644 --- a/pkg/trait/trait_test.go +++ b/pkg/trait/trait_test.go @@ -334,7 +334,7 @@ func TestConfigureVolumesAndMountsTextResourcesAndProperties(t *testing.T) { m = findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return m.Name == "test-configmap" }) assert.NotNil(t, m) - assert.Equal(t, path.Join(configConfigmapsMountPath, "test-configmap"), m.MountPath) + assert.Equal(t, path.Join(camel.ConfigConfigmapsMountPath, "test-configmap"), m.MountPath) v = findVolume(vols, func(v corev1.Volume) bool { return v.Name == "test-secret" }) assert.NotNil(t, v) @@ -343,7 +343,7 @@ func TestConfigureVolumesAndMountsTextResourcesAndProperties(t *testing.T) { m = findVVolumeMount(mnts, func(m corev1.VolumeMount) bool { return m.Name == "test-secret" }) assert.NotNil(t, m) - assert.Equal(t, path.Join(configSecretsMountPath, "test-secret"), m.MountPath) + assert.Equal(t, path.Join(camel.ConfigSecretsMountPath, "test-secret"), m.MountPath) v = findVolume(vols, func(v corev1.Volume) bool { return v.Name == "testvolume-data" }) assert.NotNil(t, v) diff --git a/pkg/trait/trait_types.go b/pkg/trait/trait_types.go index 17576148a8..bb00d49073 100644 --- a/pkg/trait/trait_types.go +++ b/pkg/trait/trait_types.go @@ -48,18 +48,7 @@ const ( False = "false" ) -var ( - basePath = "/etc/camel" - confDPath = path.Join(basePath, "conf.d") - sourcesMountPath = path.Join(basePath, "sources") - resourcesDefaultMountPath = path.Join(basePath, "resources") - configResourcesMountPath = path.Join(confDPath, "_resources") - configConfigmapsMountPath = path.Join(confDPath, "_configmaps") - configSecretsMountPath = path.Join(confDPath, "_secrets") - serviceBindingsMountPath = path.Join(confDPath, "_servicebindings") -) - -// Identifiable represent an identifiable type. +// Identifiable represent an identifiable type type Identifiable interface { ID() ID } @@ -403,7 +392,7 @@ func (e *Environment) addSourcesProperties() { } for i, s := range e.Integration.Sources() { srcName := strings.TrimPrefix(s.Name, "/") - src := "file:" + path.Join(sourcesMountPath, srcName) + src := "file:" + path.Join(camel.SourcesMountPath, srcName) e.ApplicationProperties[fmt.Sprintf("camel.k.sources[%d].location", i)] = src simpleName := srcName @@ -457,7 +446,7 @@ func (e *Environment) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c } resName := strings.TrimPrefix(s.Name, "/") refName := fmt.Sprintf("i-source-%03d", i) - resPath := path.Join(sourcesMountPath, resName) + resPath := path.Join(camel.SourcesMountPath, resName) *vols = append(*vols, corev1.Volume{ Name: refName, @@ -538,9 +527,9 @@ func (e *Environment) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c var mountPath string switch propertiesType { case "application": - mountPath = path.Join(basePath, resName) + mountPath = path.Join(camel.BasePath, resName) case "user": - mountPath = path.Join(confDPath, resName) + mountPath = path.Join(camel.ConfDPath, resName) } if propertiesType != "" { @@ -626,7 +615,7 @@ func (e *Environment) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]c *mnts = append(*mnts, corev1.VolumeMount{ Name: refName, - MountPath: path.Join(serviceBindingsMountPath, strings.ToLower(secret)), + MountPath: path.Join(camel.ServiceBindingsMountPath, strings.ToLower(secret)), }) } @@ -698,11 +687,11 @@ func getResourcePath(resourceName string, maybePath string, resourceType v1.Reso } // otherwise return a default path, according to the resource type if resourceType == v1.ResourceTypeData { - return path.Join(resourcesDefaultMountPath, resourceName) + return path.Join(camel.ResourcesDefaultMountPath, resourceName) } // Default, config type - return path.Join(configResourcesMountPath, resourceName) + return path.Join(camel.ConfigResourcesMountPath, resourceName) } func getConfigmapMountPoint(resourceName string, maybeMountPoint string, resourceType string) string { @@ -711,11 +700,11 @@ func getConfigmapMountPoint(resourceName string, maybeMountPoint string, resourc return maybeMountPoint } if resourceType == "data" { - return path.Join(resourcesDefaultMountPath, resourceName) + return path.Join(camel.ResourcesDefaultMountPath, resourceName) } // Default, config type - return path.Join(configConfigmapsMountPath, resourceName) + return path.Join(camel.ConfigConfigmapsMountPath, resourceName) } func getSecretMountPoint(resourceName string, maybeMountPoint string, resourceType string) string { @@ -724,11 +713,11 @@ func getSecretMountPoint(resourceName string, maybeMountPoint string, resourceTy return maybeMountPoint } if resourceType == "data" { - return path.Join(resourcesDefaultMountPath, resourceName) + return path.Join(camel.ResourcesDefaultMountPath, resourceName) } // Default, config type - return path.Join(configSecretsMountPath, resourceName) + return path.Join(camel.ConfigSecretsMountPath, resourceName) } func (e *Environment) collectConfigurationValues(configurationType string) []string { diff --git a/pkg/util/camel/camel_util.go b/pkg/util/camel/camel_util.go index 2aee18b9d3..f41dad240e 100644 --- a/pkg/util/camel/camel_util.go +++ b/pkg/util/camel/camel_util.go @@ -18,6 +18,7 @@ limitations under the License. package camel import ( + "path" "sort" "strings" @@ -27,6 +28,17 @@ import ( "github.com/apache/camel-k/pkg/util/log" ) +var ( + BasePath = "/etc/camel" + ConfDPath = path.Join(BasePath, "conf.d") + SourcesMountPath = path.Join(BasePath, "sources") + ResourcesDefaultMountPath = path.Join(BasePath, "resources") + ConfigResourcesMountPath = path.Join(ConfDPath, "_resources") + ConfigConfigmapsMountPath = path.Join(ConfDPath, "_configmaps") + ConfigSecretsMountPath = path.Join(ConfDPath, "_secrets") + ServiceBindingsMountPath = path.Join(ConfDPath, "_servicebindings") +) + func findBestMatch(catalogs []v1.CamelCatalog, runtime v1.RuntimeSpec) (*RuntimeCatalog, error) { for _, catalog := range catalogs { if catalog.Spec.Runtime.Version == runtime.Version && catalog.Spec.Runtime.Provider == runtime.Provider { diff --git a/pkg/util/kubernetes/factory.go b/pkg/util/kubernetes/factory.go index c1e7aa5444..6fa42ecda5 100644 --- a/pkg/util/kubernetes/factory.go +++ b/pkg/util/kubernetes/factory.go @@ -24,6 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var ( @@ -114,3 +115,34 @@ func NewResourceRequirements(reqs []string) (corev1.ResourceRequirements, error) return resReq, nil } + +// NewConfigmap will create a Configmap +func NewConfigmap(namespace, cmName, originalFilename string, generatedKey string, + textData string, binaryData []byte) *corev1.ConfigMap { + immutable := true + cm := corev1.ConfigMap{ + TypeMeta: metav1.TypeMeta{ + Kind: "ConfigMap", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: cmName, + Namespace: namespace, + Labels: map[string]string{ + "camel.apache.org/original-path": originalFilename, + }, + }, + Immutable: &immutable, + } + if textData != "" { + cm.Data = map[string]string{ + generatedKey: textData, + } + } + if binaryData != nil { + cm.BinaryData = map[string][]byte{ + generatedKey: binaryData, + } + } + return &cm +}