Skip to content

Commit

Permalink
Merge pull request #1952 from jvitor83/feature/config-content
Browse files Browse the repository at this point in the history
Add support for content in config
  • Loading branch information
k8s-ci-robot authored Dec 2, 2024
2 parents 0d989a2 + a495420 commit 62d33c4
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 5 deletions.
9 changes: 8 additions & 1 deletion docs/conversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ We're doing our best to keep it up to date as soon as possible in our releases t
| cap_add |||| Container.SecurityContext.Capabilities.Add | |
| cap_drop |||| Container.SecurityContext.Capabilities.Drop | |
| command |||| Container.Args | |
| configs | n | n || | |
| configs | n | n || | |
| configs: short-syntax | n | n || | Only create configMap |
| configs: long-syntax | n | n || | If target path is /, ignore this and only create configMap |
| cgroup_parent | x | x | x | | Not supported within Kubernetes. See issue https://github.com/kubernetes/kubernetes/issues/11986 |
Expand Down Expand Up @@ -110,3 +110,10 @@ We're doing our best to keep it up to date as soon as possible in our releases t
| internal | x | x | x | | |
| labels | x | x | x | | |
| external | x | x | x | | |
| | | | | | |
| **Configs** | x | x | x | | |
| environment | x | y | y | | |
| file | y | y | y | | |
| content | x | y | y | | |
| labels | x | x | x | | |
| external | x | x | x | | |
19 changes: 18 additions & 1 deletion pkg/kobject/kobject.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,24 @@ func (s *ServiceConfig) GetConfigMapKeyFromMeta(name string) (string, error) {
return "", errors.Errorf("config %s is external", name)
}

return filepath.Base(config.File), nil
if config.File != "" {
return filepath.Base(config.File), nil
} else if config.Content != "" {
// loop through s.Configs to find the config with the same name
for _, cfg := range s.Configs {
if cfg.Source == name {
if cfg.Target == "" {
return filepath.Base(cfg.Source), nil
} else {
return filepath.Base(cfg.Target), nil
}
}
}
} else {
return "", errors.Errorf("config %s is empty", name)
}

return "", errors.Errorf("config %s not found", name)
}

// GetKubernetesUpdateStrategy from compose update_config
Expand Down
92 changes: 92 additions & 0 deletions pkg/transformer/kubernetes/k8sutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"sort"
"testing"

"github.com/compose-spec/compose-go/v2/types"
"github.com/kubernetes/kompose/pkg/kobject"
"github.com/kubernetes/kompose/pkg/loader/compose"
"github.com/kubernetes/kompose/pkg/testutils"
Expand Down Expand Up @@ -328,6 +329,97 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
}
}

func TestCreateServiceWithConfigLongSyntax(t *testing.T) {
content := "setting: true"
target := "/etc/config.yaml"

// An example service
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
Command: []string{"cmd"},
Configs: []types.ServiceConfigObjConfig{{Source: "configmap", Target: target}},
ConfigsMetaData: map[string]types.ConfigObjConfig{"configmap": {Content: content}},
}

komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{
"app": service,
},
}

k := Kubernetes{}

objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
if err != nil {
t.Error(errors.Wrap(err, "k.Transform failed"))
}

for _, obj := range objects {
t.Log(obj)
if configMap, ok := obj.(*api.ConfigMap); ok {
fileContent := configMap.Data["config.yaml"]
if fileContent != content {
t.Errorf("Config map content not equal")
}
}
if deployment, ok := obj.(*appsv1.Deployment); ok {
spec := deployment.Spec.Template.Spec
if spec.Containers[0].VolumeMounts[0].MountPath != target {
t.Errorf("Config map mountPath not found")
}
}
}
}

func TestCreateServiceWithConfigShortSyntax(t *testing.T) {
content := "setting: true"
source := "configmap"
target := "/" + source

// An example service
service := kobject.ServiceConfig{
ContainerName: "name",
Image: "image",
Environment: []kobject.EnvVar{{Name: "env", Value: "value"}},
Port: []kobject.Ports{{HostPort: 123, ContainerPort: 456, Protocol: string(corev1.ProtocolTCP)}},
Command: []string{"cmd"},
Configs: []types.ServiceConfigObjConfig{{Source: source}},
ConfigsMetaData: map[string]types.ConfigObjConfig{source: {Content: content}},
}

komposeObject := kobject.KomposeObject{
ServiceConfigs: map[string]kobject.ServiceConfig{
"app": service,
},
}

k := Kubernetes{}

objects, err := k.Transform(komposeObject, kobject.ConvertOptions{CreateD: true, Replicas: 1})
if err != nil {
t.Error(errors.Wrap(err, "k.Transform failed"))
}

for _, obj := range objects {
t.Log(obj)
if configMap, ok := obj.(*api.ConfigMap); ok {
fileContent := configMap.Data[source]
if fileContent != content {
t.Errorf("Config map content not equal")
}
}
if deployment, ok := obj.(*appsv1.Deployment); ok {
spec := deployment.Spec.Template.Spec
if spec.Containers[0].VolumeMounts[0].MountPath != target {
t.Errorf("Config map mountPath not found")
}
}
}
}

func TestTransformWithPid(t *testing.T) {
// An example service
service := kobject.ServiceConfig{
Expand Down
38 changes: 35 additions & 3 deletions pkg/transformer/kubernetes/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,24 @@ func initConfigMapData(configMap *api.ConfigMap, data map[string]string) {
configMap.BinaryData = binData
}

// InitConfigMapFromContent initializes a ConfigMap object
func (k *Kubernetes) InitConfigMapFromContent(name string, service kobject.ServiceConfig, content string, currentConfigName string, target string) *api.ConfigMap {
configMap := &api.ConfigMap{
TypeMeta: metav1.TypeMeta{
Kind: "ConfigMap",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: currentConfigName,
Labels: transformer.ConfigLabels(name),
},
}
filename := GetFileName(target)
data := map[string]string{filename: content}
initConfigMapData(configMap, data)
return configMap
}

// InitConfigMapFromFile initializes a ConfigMap object
func (k *Kubernetes) InitConfigMapFromFile(name string, service kobject.ServiceConfig, fileName string) *api.ConfigMap {
content, err := GetContentFromFile(fileName)
Expand Down Expand Up @@ -1325,12 +1343,26 @@ func (k *Kubernetes) createConfigMapFromComposeConfig(name string, service kobje
for _, config := range service.Configs {
currentConfigName := config.Source
currentConfigObj := service.ConfigsMetaData[currentConfigName]
if config.Target == "" {
config.Target = currentConfigName
}
if currentConfigObj.External {
continue
}
currentFileName := currentConfigObj.File
configMap := k.InitConfigMapFromFile(name, service, currentFileName)
objects = append(objects, configMap)
if currentConfigObj.File != "" {
currentFileName := currentConfigObj.File
configMap := k.InitConfigMapFromFile(name, service, currentFileName)
objects = append(objects, configMap)
} else if currentConfigObj.Content != "" {
content := currentConfigObj.Content
configMap := k.InitConfigMapFromContent(name, service, content, currentConfigName, config.Target)
objects = append(objects, configMap)
} else if currentConfigObj.Environment != "" {
// TODO: Add support for environment variables in configmaps
log.Warnf("Environment variables in configmaps are not supported yet")
} else {
log.Warnf("Configmap %s is empty", currentConfigName)
}
}
return objects
}
Expand Down

0 comments on commit 62d33c4

Please sign in to comment.