diff --git a/pkg/transformer/kubernetes/k8sutils.go b/pkg/transformer/kubernetes/k8sutils.go index 2c59830a..5a48049f 100644 --- a/pkg/transformer/kubernetes/k8sutils.go +++ b/pkg/transformer/kubernetes/k8sutils.go @@ -105,13 +105,28 @@ func splitImage(image string) (string, string) { // unquoteHelmTemplates removes quotes around Helm template syntax that yaml.Marshal adds func unquoteHelmTemplates(yamlBytes []byte) []byte { yamlStr := string(yamlBytes) + lines := strings.Split(yamlStr, "\n") - // Remove quotes around any string containing Helm templates - // Handles both single templates and multiple templates in one value (e.g., image: repo:tag) - re := regexp.MustCompile(`['"]([^'"]*\{\{.+?\}\}[^'"]*?)['"]`) - yamlStr = re.ReplaceAllString(yamlStr, "$1") + for i, line := range lines { + // If line contains Helm template syntax {{...}} + if strings.Contains(line, "{{") && strings.Contains(line, "}}") { + // Remove outer quotes only - find the first and last quote on the line + // that enclose the entire value (after the colon for YAML) + if idx := strings.Index(line, ": "); idx != -1 { + prefix := line[:idx+2] // Keep "key: " + value := line[idx+2:] // Get the value part - return []byte(yamlStr) + // Remove surrounding quotes from value if present + if (strings.HasPrefix(value, `"`) && strings.HasSuffix(value, `"`)) || + (strings.HasPrefix(value, `'`) && strings.HasSuffix(value, `'`)) { + value = value[1 : len(value)-1] + } + lines[i] = prefix + value + } + } + } + + return []byte(strings.Join(lines, "\n")) } // extractValuesFromKomposeObject extracts values from KomposeObject for values.yaml diff --git a/pkg/transformer/kubernetes/kubernetes.go b/pkg/transformer/kubernetes/kubernetes.go index cb7883ad..2f6f828a 100644 --- a/pkg/transformer/kubernetes/kubernetes.go +++ b/pkg/transformer/kubernetes/kubernetes.go @@ -57,6 +57,17 @@ type Kubernetes struct { Opt kobject.ConvertOptions } +// helmValuesPath generates a Helm template path using index notation +// This works for all service names including those with hyphens +func helmValuesPath(parts ...string) string { + quotedParts := make([]string, len(parts)+1) + quotedParts[0] = ".Values" + for i, part := range parts { + quotedParts[i+1] = `"` + part + `"` + } + return "index " + strings.Join(quotedParts, " ") +} + // PVCRequestSize (Persistent Volume Claim) has default size const PVCRequestSize = "100Mi" @@ -117,7 +128,7 @@ func (k *Kubernetes) InitPodSpec(name string, service kobject.ServiceConfig, opt // Inject Helm template for chart generation if opt.CreateChart { - image = "{{ .Values." + name + ".image.repository }}:{{ .Values." + name + ".image.tag }}" + image = "{{ " + helmValuesPath(name, "image", "repository") + " }}:{{ " + helmValuesPath(name, "image", "tag") + " }}" } pod := api.PodSpec{ @@ -192,7 +203,7 @@ func (k *Kubernetes) InitPodSpecWithConfigMap(name string, service kobject.Servi // Inject Helm template for chart generation if opt.CreateChart { - image = "{{ .Values." + name + ".image.repository }}:{{ .Values." + name + ".image.tag }}" + image = "{{ " + helmValuesPath(name, "image", "repository") + " }}:{{ " + helmValuesPath(name, "image", "tag") + " }}" } pod := api.PodSpec{ @@ -1257,7 +1268,7 @@ func ConfigEnvs(service kobject.ServiceConfig, opt kobject.ConvertOptions) ([]ap value := v.Value if opt.CreateChart { // Inject Helm template syntax for chart generation - value = "{{ .Values." + service.Name + ".env." + v.Name + " | quote }}" + value = "{{ " + helmValuesPath(service.Name, "env", v.Name) + " | quote }}" } else { if strings.Contains(value, "run/secrets") { value = FormatResourceName(value)