From 7b6888edd1b7974cc4771638aabcc23fa6fb883b Mon Sep 17 00:00:00 2001 From: jose luis <2064537+sosan@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:57:24 +0100 Subject: [PATCH] customize the resource name individually via labels kompose.service.name_override Signed-off-by: jose luis <2064537+sosan@users.noreply.github.com> --- pkg/loader/compose/compose.go | 6 +- pkg/loader/compose/compose_test.go | 110 +++++++++++++++++++++++++++++ pkg/loader/compose/utils.go | 15 ++++ 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/pkg/loader/compose/compose.go b/pkg/loader/compose/compose.go index 5d6ce977..86926f1e 100644 --- a/pkg/loader/compose/compose.go +++ b/pkg/loader/compose/compose.go @@ -464,7 +464,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 @@ -792,6 +792,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 eb002e11..4f6015bb 100644 --- a/pkg/loader/compose/compose_test.go +++ b/pkg/loader/compose/compose_test.go @@ -601,3 +601,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 a101458c..98713294 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/types" "github.com/kubernetes/kompose/pkg/kobject" "github.com/pkg/errors" @@ -87,6 +88,8 @@ const ( LabelCronJobConcurrencyPolicy = "kompose.cronjob.concurrency_policy" // LabelCronJobBackoffLimit defines the job backoff limit LabelCronJobBackoffLimit = "kompose.cronjob.backoff_limit" + // LabelNameOverride defines the override resource name + LabelNameOverride = "kompose.service.name_override" ) // load environment variables from compose file @@ -194,3 +197,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 +}