You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by pc...@apache.org on 2022/01/07 13:48:26 UTC
[camel-k] 20/24: chore(trait): autogen configmap ownership
This is an automated email from the ASF dual-hosted git repository.
pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git
commit 7b643b7934994b6a6ba82d11fcb1182a053a826e
Author: Pasquale Congiusti <pa...@gmail.com>
AuthorDate: Tue Jan 4 11:38:20 2022 +0100
chore(trait): autogen configmap ownership
---
e2e/support/test_support.go | 2 +-
pkg/cmd/run.go | 30 ++++++++----------------------
pkg/cmd/run_help.go | 27 ---------------------------
pkg/trait/mount.go | 34 ++++++++++++++++++++++++++++------
pkg/trait/mount_test.go | 6 +++++-
pkg/trait/openapi.go | 4 ++++
pkg/util/kubernetes/factory.go | 13 ++++++++++---
pkg/util/resource/config.go | 2 +-
8 files changed, 57 insertions(+), 61 deletions(-)
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index 8d75eb6..319ab49 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -929,7 +929,7 @@ func AutogeneratedConfigmapsCount(ns string) func() int {
err := TestClient().List(TestContext, &lst,
ctrl.InNamespace(ns),
ctrl.MatchingLabels{
- "camel.apache.org/autogenerated": "true",
+ kubernetes.ConfigMapAutogenLabel: "true",
})
if err != nil {
panic(err)
diff --git a/pkg/cmd/run.go b/pkg/cmd/run.go
index 35f2c0a..732e1da 100644
--- a/pkg/cmd/run.go
+++ b/pkg/cmd/run.go
@@ -575,22 +575,18 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C
return nil, err
}
- generatedConfigmaps := make([]*corev1.ConfigMap, 0)
- resCms, err := o.parseAndConvertToTrait(c, integration, o.Resources, resource.ParseResource, func(c *resource.Config) string { return c.String() }, "mount.resources")
+ err = o.parseAndConvertToTrait(c, integration, o.Resources, resource.ParseResource, func(c *resource.Config) string { return c.String() }, "mount.resources")
if err != nil {
return nil, err
}
- generatedConfigmaps = append(generatedConfigmaps, resCms...)
- confCms, err := o.parseAndConvertToTrait(c, integration, o.Configs, resource.ParseConfig, func(c *resource.Config) string { return c.String() }, "mount.configs")
+ err = o.parseAndConvertToTrait(c, integration, o.Configs, resource.ParseConfig, func(c *resource.Config) string { return c.String() }, "mount.configs")
if err != nil {
return nil, err
}
- generatedConfigmaps = append(generatedConfigmaps, confCms...)
- oAPICms, err := o.parseAndConvertToTrait(c, integration, o.OpenAPIs, resource.ParseConfig, func(c *resource.Config) string { return c.Name() }, "openapi.configmaps")
+ err = o.parseAndConvertToTrait(c, integration, o.OpenAPIs, resource.ParseConfig, func(c *resource.Config) string { return c.Name() }, "openapi.configmaps")
if err != nil {
return nil, err
}
- generatedConfigmaps = append(generatedConfigmaps, oAPICms...)
for _, item := range o.Dependencies {
integration.Spec.AddDependency(item)
@@ -679,12 +675,6 @@ func (o *runCmdOptions) createOrUpdateIntegration(cmd *cobra.Command, c client.C
return nil, err
}
- if generatedConfigmaps != nil {
- err = bindGeneratedConfigmapsToIntegration(o.Context, c, integration, generatedConfigmaps)
- if err != nil {
- return integration, err
- }
- }
return integration, nil
}
@@ -692,24 +682,20 @@ func (o *runCmdOptions) parseAndConvertToTrait(
c client.Client, integration *v1.Integration, params []string,
parse func(string) (*resource.Config, error),
convert func(*resource.Config) string,
- traitParam string) ([]*corev1.ConfigMap, error) {
- generatedCms := make([]*corev1.ConfigMap, 0)
+ traitParam string) error {
for _, param := range params {
config, err := parse(param)
if err != nil {
- return nil, err
+ return err
}
// We try to autogenerate a configmap
- maybeGenCm, err := parseConfigAndGenCm(o.Context, c, config, integration, o.Compression)
+ _, err = parseConfigAndGenCm(o.Context, c, config, integration, o.Compression)
if err != nil {
- return nil, err
- }
- if maybeGenCm != nil {
- generatedCms = append(generatedCms, maybeGenCm)
+ return err
}
o.Traits = append(o.Traits, convertToTrait(convert(config), traitParam))
}
- return generatedCms, nil
+ return nil
}
func convertToTrait(value, traitParameter string) string {
diff --git a/pkg/cmd/run_help.go b/pkg/cmd/run_help.go
index e9f9758..2690154 100644
--- a/pkg/cmd/run_help.go
+++ b/pkg/cmd/run_help.go
@@ -30,7 +30,6 @@ import (
"github.com/apache/camel-k/pkg/util/resource"
"github.com/magiconair/properties"
corev1 "k8s.io/api/core/v1"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
//nolint
@@ -162,29 +161,3 @@ 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/mount.go b/pkg/trait/mount.go
index 18114bb..3fc6b74 100644
--- a/pkg/trait/mount.go
+++ b/pkg/trait/mount.go
@@ -32,15 +32,21 @@ import (
utilResource "github.com/apache/camel-k/pkg/util/resource"
)
-// The Mount trait can be used to configure volumes mounted on the Integration Pod.
+// The Mount trait can be used to configure volumes mounted on the Integration Pods.
//
// +camel-k:trait=mount
// nolint: tagliatelle
type mountTrait struct {
BaseTrait `property:",squash"`
- // A list of configuration pointing to configmap/secret. Syntax: [configmap|secret]:name[key], where name represents the resource name and key optionally represents the resource key to be filtered
+ // A list of configuration pointing to configmap/secret.
+ // The configuration are expected to be ÙTF-8 resources as they are processed by runtime Camel Context and tried to be parsed as property files.
+ // They are also made available on the classpath in order to ease their usage directly from the Route.
+ // Syntax: [configmap|secret]:name[key], where name represents the resource name and key optionally represents the resource key to be filtered
Configs []string `property:"configs" json:"configs,omitempty"`
- // A list of resources pointing to configmap/secret. Syntax: [configmap|secret]:name[/key][@path], where name represents the resource name, key optionally represents the resource key to be filtered and path represents the destination path
+ // A list of resources (text or binary content) pointing to configmap/secret.
+ // The resources are expected to be any resource type (text or binary content).
+ // The destination path can be either a default location or any path specified by the user.
+ // Syntax: [configmap|secret]:name[/key][@path], where name represents the resource name, key optionally represents the resource key to be filtered and path represents the destination path
Resources []string `property:"resources" json:"resources,omitempty"`
// A list of Persistent Volume Claims to be mounted. Syntax: [pvcname:/container/path]
Volumes []string `property:"volumes" json:"volumes,omitempty"`
@@ -58,7 +64,8 @@ func (t *mountTrait) Configure(e *Environment) (bool, error) {
return false, nil
}
- if !e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases() {
+ if e.IntegrationInPhase(v1.IntegrationPhaseInitialization) ||
+ (!e.IntegrationInPhase(v1.IntegrationPhaseInitialization) && !e.IntegrationInRunningPhases()) {
return false, nil
}
@@ -121,7 +128,7 @@ func (t *mountTrait) Apply(e *Environment) error {
// Volumes declared in the Integration resources
e.configureVolumesAndMounts(volumes, &container.VolumeMounts)
// Volumes declared in the trait config/resource options
- err := t.configureVolumesAndMounts(volumes, &container.VolumeMounts)
+ err := t.configureVolumesAndMounts(e, volumes, &container.VolumeMounts)
if err != nil {
return err
}
@@ -130,9 +137,10 @@ func (t *mountTrait) Apply(e *Environment) error {
return nil
}
-func (t *mountTrait) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]corev1.VolumeMount) error {
+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.attachResource(e, conf)
t.mountResource(vols, mnts, conf)
} else {
return parseErr
@@ -140,6 +148,7 @@ func (t *mountTrait) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]co
}
for _, r := range t.Resources {
if res, parseErr := utilResource.ParseResource(r); parseErr == nil {
+ t.attachResource(e, res)
t.mountResource(vols, mnts, res)
} else {
return parseErr
@@ -156,6 +165,19 @@ func (t *mountTrait) configureVolumesAndMounts(vols *[]corev1.Volume, mnts *[]co
return nil
}
+// attachResource is in charge to filter the autogenerated configmap and attach to the Integration resources.
+// The owner trait will be in charge to bind it accordingly.
+func (t *mountTrait) attachResource(e *Environment, conf *utilResource.Config) {
+ if conf.StorageType() == utilResource.StorageTypeConfigmap {
+ // verify if it was autogenerated
+ cm := kubernetes.LookupConfigmap(e.Ctx, e.Client, e.Integration.Namespace, conf.Name())
+ if cm != nil && cm.ObjectMeta.Labels[kubernetes.ConfigMapAutogenLabel] == "true" {
+ refCm := kubernetes.NewConfigMap(e.Integration.Namespace, conf.Name(), "", "", "", nil)
+ e.Resources.Add(refCm)
+ }
+ }
+}
+
func (t *mountTrait) mountResource(vols *[]corev1.Volume, mnts *[]corev1.VolumeMount, conf *utilResource.Config) {
refName := kubernetes.SanitizeLabel(conf.Name())
vol := getVolume(refName, string(conf.StorageType()), conf.Name(), conf.Key(), conf.Key())
diff --git a/pkg/trait/mount_test.go b/pkg/trait/mount_test.go
index eee4bc0..9221244 100644
--- a/pkg/trait/mount_test.go
+++ b/pkg/trait/mount_test.go
@@ -18,6 +18,7 @@ limitations under the License.
package trait
import (
+ "context"
"testing"
"github.com/stretchr/testify/assert"
@@ -114,7 +115,7 @@ func TestMountVolumesIntegrationPhaseInitialization(t *testing.T) {
assert.Nil(t, err)
assert.NotEmpty(t, environment.ExecutedTraits)
- assert.NotNil(t, environment.GetTrait("mount"))
+ assert.Nil(t, environment.GetTrait("mount"))
s := environment.Resources.GetDeployment(func(service *appsv1.Deployment) bool {
return service.Name == "hello"
@@ -124,12 +125,15 @@ func TestMountVolumesIntegrationPhaseInitialization(t *testing.T) {
func getNominalEnv(t *testing.T, traitCatalog *Catalog) *Environment {
t.Helper()
+ fakeClient, _ := test.NewFakeClient()
catalog, _ := camel.DefaultCatalog()
compressedRoute, _ := gzip.CompressBase64([]byte(`from("undertow:test").log("hello")`))
return &Environment{
CamelCatalog: catalog,
Catalog: traitCatalog,
+ Ctx: context.Background(),
+ Client: fakeClient,
Integration: &v1.Integration{
ObjectMeta: metav1.ObjectMeta{
Name: "hello",
diff --git a/pkg/trait/openapi.go b/pkg/trait/openapi.go
index 43c8791..24f49b7 100644
--- a/pkg/trait/openapi.go
+++ b/pkg/trait/openapi.go
@@ -140,6 +140,10 @@ func (t *openAPITrait) generateFromConfigmaps(e *Environment, tmpDir string) ([]
if cm == nil {
return nil, fmt.Errorf("could not find any configmap with name: %s", configmap)
}
+ if cm.ObjectMeta.Labels[kubernetes.ConfigMapAutogenLabel] == "true" {
+ refCm := kubernetes.NewConfigMap(e.Integration.Namespace, configmap, "", "", "", nil)
+ e.Resources.Add(refCm)
+ }
// Iterate over each configmap key which may hold a different OpenAPI spec
for k, v := range cm.Data {
dataSpecs = append(dataSpecs, v1.DataSpec{
diff --git a/pkg/util/kubernetes/factory.go b/pkg/util/kubernetes/factory.go
index 9d32be1..c79b76b 100644
--- a/pkg/util/kubernetes/factory.go
+++ b/pkg/util/kubernetes/factory.go
@@ -33,6 +33,12 @@ var (
validResourceRequirementsRegexp = regexp.MustCompile(`^(requests|limits)\.(memory|cpu)=([\w\.]+)$`)
)
+// ConfigMapAutogenLabel -- .
+const ConfigMapAutogenLabel = "camel.apache.org/generated"
+
+// ConfigMapOriginalFileNameLabel -- .
+const ConfigMapOriginalFileNameLabel = "camel.apache.org/filename"
+
// NewTolerations build an array of Tolerations from an array of string.
func NewTolerations(taints []string) ([]corev1.Toleration, error) {
tolerations := make([]corev1.Toleration, 0)
@@ -116,8 +122,8 @@ func NewResourceRequirements(reqs []string) (corev1.ResourceRequirements, error)
return resReq, nil
}
-// NewConfigmap will create a Configmap.
-func NewConfigmap(namespace, cmName, originalFilename string, generatedKey string,
+// NewConfigMap will create a ConfigMap.
+func NewConfigMap(namespace, cmName, originalFilename string, generatedKey string,
textData string, binaryData []byte) *corev1.ConfigMap {
immutable := true
cm := corev1.ConfigMap{
@@ -129,7 +135,8 @@ func NewConfigmap(namespace, cmName, originalFilename string, generatedKey strin
Name: cmName,
Namespace: namespace,
Labels: map[string]string{
- "camel.apache.org/filename": originalFilename,
+ ConfigMapOriginalFileNameLabel: originalFilename,
+ ConfigMapAutogenLabel: "true",
},
},
Immutable: &immutable,
diff --git a/pkg/util/resource/config.go b/pkg/util/resource/config.go
index 41b0176..56703a4 100644
--- a/pkg/util/resource/config.go
+++ b/pkg/util/resource/config.go
@@ -232,7 +232,7 @@ func ConvertFileToConfigmap(ctx context.Context, c client.Client, config *Config
config.destinationPath = filepath.Dir(config.DestinationPath())
}
genCmName := fmt.Sprintf("cm-%s", hashFrom([]byte(integrationName), []byte(content), rawContent))
- cm := kubernetes.NewConfigmap(namespace, genCmName, filepath.Base(config.Name()), config.Key(), content, rawContent)
+ cm := kubernetes.NewConfigMap(namespace, genCmName, filepath.Base(config.Name()), config.Key(), content, rawContent)
err := c.Create(ctx, cm)
if err != nil {
if k8serrors.IsAlreadyExists(err) {