diff --git a/pkg/loader/compose/compose.go b/pkg/loader/compose/compose.go index e2439cbd..2eaa5dc1 100644 --- a/pkg/loader/compose/compose.go +++ b/pkg/loader/compose/compose.go @@ -465,7 +465,7 @@ func dockerComposeToKomposeMapping(composeObject *types.Project) (kobject.Kompos for _, composeServiceConfig := range composeObject.Services { // Standard import // No need to modify before importation - name := strings.ToLower(composeServiceConfig.Name) + name := parseResourceName(composeServiceConfig.Name, composeServiceConfig.Labels) serviceConfig := kobject.ServiceConfig{} serviceConfig.Name = name serviceConfig.Image = composeServiceConfig.Image @@ -801,6 +801,10 @@ func parseKomposeLabels(labels map[string]string, serviceConfig *kobject.Service } serviceConfig.CronJobBackoffLimit = cronJobBackoffLimit + case LabelNameOverride: + // generate a valid k8s resource name + normalizedName := normalizeServiceNames(value) + serviceConfig.Name = normalizedName default: serviceConfig.Labels[key] = value } diff --git a/pkg/loader/compose/compose_test.go b/pkg/loader/compose/compose_test.go index af9dfa5a..6fd7f439 100644 --- a/pkg/loader/compose/compose_test.go +++ b/pkg/loader/compose/compose_test.go @@ -647,3 +647,113 @@ func checkConstraints(t *testing.T, caseName string, output, expected map[string } } } + +func Test_parseKomposeLabels(t *testing.T) { + service := kobject.ServiceConfig{ + Name: "name", + ContainerName: "containername", + Image: "image", + Labels: nil, + Annotations: map[string]string{"abc": "def"}, + Restart: "always", + } + + type args struct { + labels types.Labels + serviceConfig *kobject.ServiceConfig + } + tests := []struct { + name string + args args + expected *kobject.ServiceConfig + }{ + { + name: "override with overriding", + args: args{ + labels: types.Labels{ + LabelNameOverride: "overriding", + }, + serviceConfig: &service, + }, + expected: &kobject.ServiceConfig{ + Name: "overriding", + }, + }, + { + name: "override", + args: args{ + labels: types.Labels{ + LabelNameOverride: "overriding-resource-name", + }, + serviceConfig: &service, + }, + expected: &kobject.ServiceConfig{ + Name: "overriding-resource-name", + }, + }, + { + name: "hyphen in the middle", + args: args{ + labels: types.Labels{ + LabelNameOverride: "overriding_resource-name", + }, + serviceConfig: &service, + }, + expected: &kobject.ServiceConfig{ + Name: "overriding-resource-name", + }, + }, + { + name: "hyphen in the middle with mays", + args: args{ + labels: types.Labels{ + LabelNameOverride: "OVERRIDING_RESOURCE-NAME", + }, + serviceConfig: &service, + }, + expected: &kobject.ServiceConfig{ + Name: "overriding-resource-name", + }, + }, + // This is a corner case that is expected to fail because + // it does not account for scenarios where the string + // starts or ends with a '-' or any other character + // this test will fail with current tests + // { + // name: "Add a prefix with a dash at the start and end, with a hyphen in the middle.", + // args: args{ + // labels: types.Labels{ + // LabelNameOverride: "-OVERRIDING_RESOURCE-NAME-", + // }, + // serviceConfig: &service, + // }, + // expected: &kobject.ServiceConfig{ + // Name: "overriding-resource-name", + // }, + // }, + // not fail + { + name: "Add a prefix with a dash at the start and end, with a hyphen in the middle.", + args: args{ + labels: types.Labels{ + LabelNameOverride: "-OVERRIDING_RESOURCE-NAME-", + }, + serviceConfig: &service, + }, + expected: &kobject.ServiceConfig{ + Name: "-overriding-resource-name-", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := parseKomposeLabels(tt.args.labels, tt.args.serviceConfig); err != nil { + t.Errorf("parseKomposeLabels(): %v", err) + } + + if tt.expected.Name != tt.args.serviceConfig.Name { + t.Errorf("Name are not equal, expected: %v, output: %v", tt.expected.Name, tt.args.serviceConfig.Name) + } + }) + } +} diff --git a/pkg/loader/compose/utils.go b/pkg/loader/compose/utils.go index 92b4062c..245b8cb4 100644 --- a/pkg/loader/compose/utils.go +++ b/pkg/loader/compose/utils.go @@ -22,6 +22,7 @@ import ( "regexp" "strings" + "github.com/compose-spec/compose-go/v2/types" "github.com/kubernetes/kompose/pkg/kobject" "github.com/pkg/errors" @@ -101,6 +102,8 @@ const ( LabelHpaCPU = "kompose.hpa.cpu" // LabelHpaMemory defines scaling decisions based on memory utilization LabelHpaMemory = "kompose.hpa.memory" + // LabelNameOverride defines the override resource name + LabelNameOverride = "kompose.service.name_override" ) // load environment variables from compose file @@ -208,3 +211,15 @@ func ReadFile(fileName string) ([]byte, error) { } return os.ReadFile(fileName) } + +// Choose normalized name from resource in case exist LabelNameOverride +// from label +func parseResourceName(resourceName string, labels types.Labels) string { + // Opted to use normalizeContainerNames over normalizeServiceNames + // as in tests, normalization is only to lowercase. + normalizedName := normalizeContainerNames(resourceName) + if labelValue, exist := labels[LabelNameOverride]; exist { + normalizedName = normalizeContainerNames(labelValue) + } + return normalizedName +}