Inject templates while building the chart

This commit is contained in:
Prathamesh Musale 2025-11-27 12:23:38 +05:30
parent 3074b5451d
commit 408cd36ad3
5 changed files with 104 additions and 156 deletions

View File

@ -102,133 +102,49 @@ func splitImage(image string) (string, string) {
return image, "latest" return image, "latest"
} }
// extractImageValues extracts image information from Deployment and StatefulSet objects // unquoteHelmTemplates removes quotes around Helm template syntax that yaml.Marshal adds
func extractImageValues(objects []runtime.Object) map[string]ServiceValues { func unquoteHelmTemplates(yamlBytes []byte) []byte {
yamlStr := string(yamlBytes)
// 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")
return []byte(yamlStr)
}
// extractValuesFromKomposeObject extracts values from KomposeObject for values.yaml
func extractValuesFromKomposeObject(komposeObject kobject.KomposeObject) map[string]ServiceValues {
values := make(map[string]ServiceValues) values := make(map[string]ServiceValues)
for _, obj := range objects { for serviceName, service := range komposeObject.ServiceConfigs {
switch o := obj.(type) { svcValues := ServiceValues{}
case *appsv1.Deployment:
serviceName := o.ObjectMeta.Name
if len(o.Spec.Template.Spec.Containers) > 0 {
container := o.Spec.Template.Spec.Containers[0]
repo, tag := splitImage(container.Image) // Extract image
pullPolicy := string(container.ImagePullPolicy) repo, tag := splitImage(service.Image)
svcValues.Image.Repository = repo
svcValues.Image.Tag = tag
// Extract pull policy
pullPolicy := service.ImagePullPolicy
if pullPolicy == "" { if pullPolicy == "" {
pullPolicy = "IfNotPresent" pullPolicy = "IfNotPresent"
} }
svcValues := ServiceValues{}
svcValues.Image.Repository = repo
svcValues.Image.Tag = tag
svcValues.Image.PullPolicy = pullPolicy svcValues.Image.PullPolicy = pullPolicy
// Extract env vars // Extract env vars
svcValues.Env = make(map[string]string) svcValues.Env = make(map[string]string)
for _, envVar := range container.Env { for _, envVar := range service.Environment {
svcValues.Env[envVar.Name] = envVar.Value svcValues.Env[envVar.Name] = envVar.Value
} }
values[serviceName] = svcValues values[serviceName] = svcValues
} }
case *appsv1.StatefulSet:
serviceName := o.ObjectMeta.Name
if len(o.Spec.Template.Spec.Containers) > 0 {
container := o.Spec.Template.Spec.Containers[0]
repo, tag := splitImage(container.Image)
pullPolicy := string(container.ImagePullPolicy)
if pullPolicy == "" {
pullPolicy = "IfNotPresent"
}
svcValues := ServiceValues{}
svcValues.Image.Repository = repo
svcValues.Image.Tag = tag
svcValues.Image.PullPolicy = pullPolicy
// Extract env vars
svcValues.Env = make(map[string]string)
for _, envVar := range container.Env {
svcValues.Env[envVar.Name] = envVar.Value
}
values[serviceName] = svcValues
}
}
}
return values return values
} }
// templatizeImage replaces image and imagePullPolicy with Helm template syntax
func templatizeImage(yamlBytes []byte, serviceName string, values map[string]ServiceValues) []byte {
if svcValues, ok := values[serviceName]; ok {
yamlStr := string(yamlBytes)
// Replace image line
originalImage := svcValues.Image.Repository + ":" + svcValues.Image.Tag
templatedImage := "{{ .Values." + serviceName + ".image.repository }}:{{ .Values." + serviceName + ".image.tag }}"
yamlStr = strings.Replace(yamlStr, "image: "+originalImage, "image: "+templatedImage, 1)
// Replace imagePullPolicy line
if svcValues.Image.PullPolicy != "" {
originalPolicy := "imagePullPolicy: " + svcValues.Image.PullPolicy
templatedPolicy := "imagePullPolicy: {{ .Values." + serviceName + ".image.pullPolicy }}"
yamlStr = strings.Replace(yamlStr, originalPolicy, templatedPolicy, 1)
}
return []byte(yamlStr)
}
return yamlBytes
}
// templatizeEnv replaces env var values with Helm template syntax
func templatizeEnv(yamlBytes []byte, serviceName string, values map[string]ServiceValues) []byte {
if svcValues, ok := values[serviceName]; ok {
yamlStr := string(yamlBytes)
for envName, envValue := range svcValues.Env {
template := "{{ .Values." + serviceName + ".env." + envName + " | quote }}"
if envValue != "" {
// Match: name: ENVNAME\n<spaces>value: "VALUE" or value: VALUE
// Replace with: name: ENVNAME\n<spaces>value: TEMPLATE
pattern := `(name: ` + regexp.QuoteMeta(envName) + `)\n(\s+)value: (?:"` + regexp.QuoteMeta(envValue) + `"|` + regexp.QuoteMeta(envValue) + `)`
replacement := `${1}` + "\n" + `${2}value: ` + template
re := regexp.MustCompile(pattern)
yamlStr = re.ReplaceAllString(yamlStr, replacement)
} else {
// For empty values, handle two cases:
// 1. name: ENVNAME\n<spaces>value: ""
// 2. name: ENVNAME\n - name: (no value field)
// Try to replace existing empty value first
pattern1 := `(name: ` + regexp.QuoteMeta(envName) + `)\n(\s+)value: ""`
replacement1 := `${1}` + "\n" + `${2}value: ` + template
re1 := regexp.MustCompile(pattern1)
newYamlStr := re1.ReplaceAllString(yamlStr, replacement1)
// If nothing was replaced, insert value field after name
if newYamlStr == yamlStr {
// Match the current list item with its indentation
pattern2 := `(\s+)- (name: ` + regexp.QuoteMeta(envName) + `)\n`
replacement2 := "${1}- ${2}${1} value: " + template + "\n"
re2 := regexp.MustCompile(pattern2)
yamlStr = re2.ReplaceAllString(yamlStr, replacement2)
} else {
yamlStr = newYamlStr
}
}
}
return []byte(yamlStr)
}
return yamlBytes
}
/** /**
* Generate Helm Chart configuration * Generate Helm Chart configuration
*/ */
@ -415,9 +331,9 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions, komposeObje
var files []string var files []string
var imageValues map[string]ServiceValues var imageValues map[string]ServiceValues
// Extract image values for chart templating (before processing) // Extract values from KomposeObject for values.yaml
if opt.CreateChart { if opt.CreateChart {
imageValues = extractImageValues(objects) imageValues = extractValuesFromKomposeObject(komposeObject)
} }
// if asked to print to stdout or to put in single file // if asked to print to stdout or to put in single file
@ -437,6 +353,12 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions, komposeObje
if err != nil { if err != nil {
return fmt.Errorf("error in marshalling the List: %v", err) return fmt.Errorf("error in marshalling the List: %v", err)
} }
// Unquote Helm templates if generating chart
if opt.CreateChart {
data = unquoteHelmTemplates(data)
}
// this part add --- which unifies the file // this part add --- which unifies the file
data = []byte(fmt.Sprintf("---\n%s", data)) data = []byte(fmt.Sprintf("---\n%s", data))
printVal, err := transformer.Print("", dirName, "", data, opt.ToStdout, opt.GenerateJSON, f, opt.Provider) printVal, err := transformer.Print("", dirName, "", data, opt.ToStdout, opt.GenerateJSON, f, opt.Provider)
@ -485,10 +407,9 @@ func PrintList(objects []runtime.Object, opt kobject.ConvertOptions, komposeObje
objectMeta = val.FieldByName("ObjectMeta").Interface().(metav1.ObjectMeta) objectMeta = val.FieldByName("ObjectMeta").Interface().(metav1.ObjectMeta)
} }
// Templatize YAML if generating chart // Unquote Helm templates if generating chart
if opt.CreateChart && imageValues != nil { if opt.CreateChart {
data = templatizeEnv(data, objectMeta.Name, imageValues) data = unquoteHelmTemplates(data)
data = templatizeImage(data, objectMeta.Name, imageValues)
} }
file, err = transformer.Print(objectMeta.Name, finalDirName, strings.ToLower(typeMeta.Kind), data, opt.ToStdout, opt.GenerateJSON, f, opt.Provider) file, err = transformer.Print(objectMeta.Name, finalDirName, strings.ToLower(typeMeta.Kind), data, opt.ToStdout, opt.GenerateJSON, f, opt.Provider)

View File

@ -109,10 +109,17 @@ func (k *Kubernetes) CheckUnsupportedKey(komposeObject *kobject.KomposeObject, u
} }
// InitPodSpec creates the pod specification // InitPodSpec creates the pod specification
func (k *Kubernetes) InitPodSpec(name string, image string, pullSecret string) api.PodSpec { func (k *Kubernetes) InitPodSpec(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) api.PodSpec {
image := service.Image
if image == "" { if image == "" {
image = name image = name
} }
// Inject Helm template for chart generation
if opt.CreateChart {
image = "{{ .Values." + name + ".image.repository }}:{{ .Values." + name + ".image.tag }}"
}
pod := api.PodSpec{ pod := api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
@ -121,10 +128,11 @@ func (k *Kubernetes) InitPodSpec(name string, image string, pullSecret string) a
}, },
}, },
} }
if pullSecret != "" {
if service.ImagePullSecret != "" {
pod.ImagePullSecrets = []api.LocalObjectReference{ pod.ImagePullSecrets = []api.LocalObjectReference{
{ {
Name: pullSecret, Name: service.ImagePullSecret,
}, },
} }
} }
@ -132,7 +140,7 @@ func (k *Kubernetes) InitPodSpec(name string, image string, pullSecret string) a
} }
// InitPodSpecWithConfigMap creates the pod specification // InitPodSpecWithConfigMap creates the pod specification
func (k *Kubernetes) InitPodSpecWithConfigMap(name string, image string, service kobject.ServiceConfig) api.PodSpec { func (k *Kubernetes) InitPodSpecWithConfigMap(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) api.PodSpec {
var volumeMounts []api.VolumeMount var volumeMounts []api.VolumeMount
var volumes []api.Volume var volumes []api.Volume
@ -177,6 +185,16 @@ func (k *Kubernetes) InitPodSpecWithConfigMap(name string, image string, service
volumes = append(volumes, cmVol) volumes = append(volumes, cmVol)
} }
image := service.Image
if image == "" {
image = name
}
// Inject Helm template for chart generation
if opt.CreateChart {
image = "{{ .Values." + name + ".image.repository }}:{{ .Values." + name + ".image.tag }}"
}
pod := api.PodSpec{ pod := api.PodSpec{
Containers: []api.Container{ Containers: []api.Container{
{ {
@ -412,12 +430,12 @@ func (k *Kubernetes) InitConfigMapFromFile(name string, service kobject.ServiceC
} }
// InitD initializes Kubernetes Deployment object // InitD initializes Kubernetes Deployment object
func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas int) *appsv1.Deployment { func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas int, opt kobject.ConvertOptions) *appsv1.Deployment {
var podSpec api.PodSpec var podSpec api.PodSpec
if len(service.Configs) > 0 { if len(service.Configs) > 0 {
podSpec = k.InitPodSpecWithConfigMap(name, service.Image, service) podSpec = k.InitPodSpecWithConfigMap(name, service, opt)
} else { } else {
podSpec = k.InitPodSpec(name, service.Image, service.ImagePullSecret) podSpec = k.InitPodSpec(name, service, opt)
} }
rp := int32(replicas) rp := int32(replicas)
@ -468,7 +486,7 @@ func (k *Kubernetes) InitD(name string, service kobject.ServiceConfig, replicas
} }
// InitDS initializes Kubernetes DaemonSet object // InitDS initializes Kubernetes DaemonSet object
func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig) *appsv1.DaemonSet { func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) *appsv1.DaemonSet {
ds := &appsv1.DaemonSet{ ds := &appsv1.DaemonSet{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "DaemonSet", Kind: "DaemonSet",
@ -483,7 +501,7 @@ func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig) *appsv1.
MatchLabels: transformer.ConfigLabels(name), MatchLabels: transformer.ConfigLabels(name),
}, },
Template: api.PodTemplateSpec{ Template: api.PodTemplateSpec{
Spec: k.InitPodSpec(name, service.Image, service.ImagePullSecret), Spec: k.InitPodSpec(name, service, opt),
}, },
}, },
} }
@ -491,12 +509,12 @@ func (k *Kubernetes) InitDS(name string, service kobject.ServiceConfig) *appsv1.
} }
// InitSS method initialize a stateful set // InitSS method initialize a stateful set
func (k *Kubernetes) InitSS(name string, service kobject.ServiceConfig, replicas int) *appsv1.StatefulSet { func (k *Kubernetes) InitSS(name string, service kobject.ServiceConfig, replicas int, opt kobject.ConvertOptions) *appsv1.StatefulSet {
var podSpec api.PodSpec var podSpec api.PodSpec
if len(service.Configs) > 0 { if len(service.Configs) > 0 {
podSpec = k.InitPodSpecWithConfigMap(name, service.Image, service) podSpec = k.InitPodSpecWithConfigMap(name, service, opt)
} else { } else {
podSpec = k.InitPodSpec(name, service.Image, service.ImagePullSecret) podSpec = k.InitPodSpec(name, service, opt)
} }
rp := int32(replicas) rp := int32(replicas)
ds := &appsv1.StatefulSet{ ds := &appsv1.StatefulSet{
@ -523,7 +541,7 @@ func (k *Kubernetes) InitSS(name string, service kobject.ServiceConfig, replicas
} }
// InitCJ initializes Kubernetes CronJob object // InitCJ initializes Kubernetes CronJob object
func (k *Kubernetes) InitCJ(name string, service kobject.ServiceConfig, schedule string, concurrencyPolicy batchv1.ConcurrencyPolicy, backoffLimit *int32) *batchv1.CronJob { func (k *Kubernetes) InitCJ(name string, service kobject.ServiceConfig, schedule string, concurrencyPolicy batchv1.ConcurrencyPolicy, backoffLimit *int32, opt kobject.ConvertOptions) *batchv1.CronJob {
cj := &batchv1.CronJob{ cj := &batchv1.CronJob{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "CronJob", Kind: "CronJob",
@ -540,7 +558,7 @@ func (k *Kubernetes) InitCJ(name string, service kobject.ServiceConfig, schedule
Spec: batchv1.JobSpec{ Spec: batchv1.JobSpec{
BackoffLimit: backoffLimit, BackoffLimit: backoffLimit,
Template: api.PodTemplateSpec{ Template: api.PodTemplateSpec{
Spec: k.InitPodSpec(name, service.Image, service.ImagePullSecret), Spec: k.InitPodSpec(name, service, opt),
}, },
}, },
}, },
@ -1225,12 +1243,18 @@ func ConfigEnvs(service kobject.ServiceConfig, opt kobject.ConvertOptions) ([]ap
// Load up the environment variables // Load up the environment variables
for _, v := range service.Environment { for _, v := range service.Environment {
if !keysFromEnvFile[v.Name] { if !keysFromEnvFile[v.Name] {
if strings.Contains(v.Value, "run/secrets") { value := v.Value
v.Value = FormatResourceName(v.Value) if opt.CreateChart {
// Inject Helm template syntax for chart generation
value = "{{ .Values." + service.Name + ".env." + v.Name + " | quote }}"
} else {
if strings.Contains(value, "run/secrets") {
value = FormatResourceName(value)
}
} }
envs = append(envs, api.EnvVar{ envs = append(envs, api.EnvVar{
Name: v.Name, Name: v.Name,
Value: v.Value, Value: value,
}) })
} }
} }
@ -1347,15 +1371,15 @@ func (k *Kubernetes) CreateWorkloadAndConfigMapObjects(name string, service kobj
} }
if opt.CreateD || opt.Controller == DeploymentController { if opt.CreateD || opt.Controller == DeploymentController {
objects = append(objects, k.InitD(name, service, replica)) objects = append(objects, k.InitD(name, service, replica, opt))
} }
if opt.CreateDS || opt.Controller == DaemonSetController { if opt.CreateDS || opt.Controller == DaemonSetController {
objects = append(objects, k.InitDS(name, service)) objects = append(objects, k.InitDS(name, service, opt))
} }
if opt.Controller == StatefulStateController { if opt.Controller == StatefulStateController {
objects = append(objects, k.InitSS(name, service, replica)) objects = append(objects, k.InitSS(name, service, replica, opt))
} }
envConfigMaps := k.PargeEnvFiletoConfigMaps(name, service, opt) envConfigMaps := k.PargeEnvFiletoConfigMaps(name, service, opt)
@ -1392,7 +1416,7 @@ func (k *Kubernetes) createConfigMapFromComposeConfig(name string, service kobje
} }
// InitPod initializes Kubernetes Pod object // InitPod initializes Kubernetes Pod object
func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig) *api.Pod { func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig, opt kobject.ConvertOptions) *api.Pod {
pod := api.Pod{ pod := api.Pod{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "Pod", Kind: "Pod",
@ -1403,7 +1427,7 @@ func (k *Kubernetes) InitPod(name string, service kobject.ServiceConfig) *api.Po
Labels: transformer.ConfigLabels(name), Labels: transformer.ConfigLabels(name),
Annotations: transformer.ConfigAnnotations(service), Annotations: transformer.ConfigAnnotations(service),
}, },
Spec: k.InitPodSpec(name, service.Image, service.ImagePullSecret), Spec: k.InitPodSpec(name, service, opt),
} }
return &pod return &pod
} }
@ -1692,10 +1716,10 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
if (service.Restart == "no" || service.Restart == "on-failure") && !opt.IsPodController() { if (service.Restart == "no" || service.Restart == "on-failure") && !opt.IsPodController() {
if service.CronJobSchedule != "" { if service.CronJobSchedule != "" {
log.Infof("Create kubernetes pod instead of pod controller due to restart policy: %s", service.Restart) log.Infof("Create kubernetes pod instead of pod controller due to restart policy: %s", service.Restart)
cronJob := k.InitCJ(name, service, service.CronJobSchedule, service.CronJobConcurrencyPolicy, service.CronJobBackoffLimit) cronJob := k.InitCJ(name, service, service.CronJobSchedule, service.CronJobConcurrencyPolicy, service.CronJobBackoffLimit, opt)
objects = append(objects, cronJob) objects = append(objects, cronJob)
} else { } else {
pod := k.InitPod(name, service) pod := k.InitPod(name, service, opt)
objects = append(objects, pod) objects = append(objects, pod)
} }
envConfigMaps := k.PargeEnvFiletoConfigMaps(name, service, opt) envConfigMaps := k.PargeEnvFiletoConfigMaps(name, service, opt)

View File

@ -611,7 +611,9 @@ func TestRestartOnFailure(t *testing.T) {
func TestInitPodSpec(t *testing.T) { func TestInitPodSpec(t *testing.T) {
name := "foo" name := "foo"
k := Kubernetes{} k := Kubernetes{}
result := k.InitPodSpec(name, newServiceConfig().Image, "") service := newServiceConfig()
opt := kobject.ConvertOptions{}
result := k.InitPodSpec(name, service, opt)
if result.Containers[0].Name != "foo" && result.Containers[0].Image != "image" { if result.Containers[0].Name != "foo" && result.Containers[0].Image != "image" {
t.Fatalf("Pod object not found") t.Fatalf("Pod object not found")
} }

View File

@ -151,7 +151,7 @@ func initBuildConfig(name string, service kobject.ServiceConfig, repo string, br
} }
// initDeploymentConfig initializes OpenShifts DeploymentConfig object // initDeploymentConfig initializes OpenShifts DeploymentConfig object
func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceConfig, replicas int) *deployapi.DeploymentConfig { func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceConfig, replicas int, opt kobject.ConvertOptions) *deployapi.DeploymentConfig {
containerName := []string{name} containerName := []string{name}
// Properly add tags to the image name // Properly add tags to the image name
@ -164,9 +164,9 @@ func (o *OpenShift) initDeploymentConfig(name string, service kobject.ServiceCon
var podSpec corev1.PodSpec var podSpec corev1.PodSpec
if len(service.Configs) > 0 { if len(service.Configs) > 0 {
podSpec = o.InitPodSpecWithConfigMap(name, " ", service) podSpec = o.InitPodSpecWithConfigMap(name, service, opt)
} else { } else {
podSpec = o.InitPodSpec(name, " ", "") podSpec = o.InitPodSpec(name, service, opt)
} }
dc := &deployapi.DeploymentConfig{ dc := &deployapi.DeploymentConfig{
@ -333,10 +333,10 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
} }
if service.CronJobSchedule != "" { if service.CronJobSchedule != "" {
cronJob := o.InitCJ(name, service, service.CronJobSchedule, service.CronJobConcurrencyPolicy, service.CronJobBackoffLimit) cronJob := o.InitCJ(name, service, service.CronJobSchedule, service.CronJobConcurrencyPolicy, service.CronJobBackoffLimit, opt)
objects = append(objects, cronJob) objects = append(objects, cronJob)
} else { } else {
pod := o.InitPod(name, service) pod := o.InitPod(name, service, opt)
objects = append(objects, pod) objects = append(objects, pod)
} }
@ -346,7 +346,7 @@ func (o *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
objects = o.CreateWorkloadAndConfigMapObjects(name, service, opt) objects = o.CreateWorkloadAndConfigMapObjects(name, service, opt)
if opt.CreateDeploymentConfig { if opt.CreateDeploymentConfig {
objects = append(objects, o.initDeploymentConfig(name, service, replica)) // OpenShift DeploymentConfigs objects = append(objects, o.initDeploymentConfig(name, service, replica, opt)) // OpenShift DeploymentConfigs
// create ImageStream after deployment (creating IS will trigger new deployment) // create ImageStream after deployment (creating IS will trigger new deployment)
objects = append(objects, o.initImageStream(name, service, opt)) objects = append(objects, o.initImageStream(name, service, opt))
} }

View File

@ -75,7 +75,7 @@ func TestOpenShiftUpdateKubernetesObjects(t *testing.T) {
serviceConfig := newServiceConfig() serviceConfig := newServiceConfig()
opt := kobject.ConvertOptions{} opt := kobject.ConvertOptions{}
object = append(object, o.initDeploymentConfig("foobar", serviceConfig, 3)) object = append(object, o.initDeploymentConfig("foobar", serviceConfig, 3, opt))
o.UpdateKubernetesObjects("foobar", serviceConfig, opt, &object) o.UpdateKubernetesObjects("foobar", serviceConfig, opt, &object)
for _, obj := range object { for _, obj := range object {
@ -95,7 +95,8 @@ func TestOpenShiftUpdateKubernetesObjects(t *testing.T) {
func TestInitDeploymentConfig(t *testing.T) { func TestInitDeploymentConfig(t *testing.T) {
o := OpenShift{} o := OpenShift{}
spec := o.initDeploymentConfig("foobar", newServiceConfig(), 1) opt := kobject.ConvertOptions{}
spec := o.initDeploymentConfig("foobar", newServiceConfig(), 1, opt)
// Check that "foobar" is used correctly as a name // Check that "foobar" is used correctly as a name
if spec.Spec.Template.Spec.Containers[0].Name != "foobar" { if spec.Spec.Template.Spec.Containers[0].Name != "foobar" {