Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for content in config #1952

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -231,6 +232,97 @@ func TestCreateServiceWithServiceUser(t *testing.T) {
}
}

func TestCreateServiceWithConfigLongSyntax(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cdrage are the e2e tests still running?

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
}

// InitConfigMapFromFile initializes a ConfigMap object
jvitor83 marked this conversation as resolved.
Show resolved Hide resolved
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