How to fix `can't evaluate field extraHosts in type interface {}` in _helpers.tpl in helm

8/5/2019

I am trying to get some values from Umbrella chart in helm in _helpers.tpl but I for some reason I am getting the error executing "gluu.ldaplist" at <.Values.ldap.extraHo...>: can't evaluate field extraHosts in type interface {}

This is what I am trying to do. _helpers.ptl

{{- define "gluu.ldaplist" -}}
{{- $hosts := .Values.ldap.extraHosts -}}
{{- $genLdap := dict "host" (printf "%s-%s" .Release.Name .Values.ldapType) "port" .Values.ldapPort -}}
{{- $hosts := prepend $hosts $genLdap -}}
{{- $local := dict "first" true -}}
{{- range $k, $v := $hosts -}}
{{- if not $local.first -}},{{- end -}}{{- printf "%s:%.f" $v.host $v.port -}}{{- $_ := set $local "first" false -}}
{{- end -}}
{{- end -}}

And this is part of values.yml for the umbrella chart values.yml

ldap:
  enabled: true
  type: opendj
  extraHosts: [
    host: opendj,
    port: 3434
  ] #array of k,v e.g host: host1, port: port1

Directory structure

helm/
  charts/
     chart_a/
       templates/
          configMap.yml ----->>> this is where I want to use it
  templates/
     _helpers.tpl ---->>>> where the failing function is
  requirements.yml
  values.yml ---------->>> where the ldap values are

The configMap.yml looks like below

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{ template "oxauth.fullname" . }}-cm
data:
  GLUU_CONFIG_ADAPTER: {{ .Values.global.configAdapterName | quote }}
  GLUU_LDAP_URL: {{ template "gluu.ldaplist" . }}

NOTE: The _helpers.tpl is under the main/umbrella chart. chart_a is a subchart.

Expected results are something like GLUU_LDAP_URL:"opendj:3434"

Helm version:

Client: &version.Version{SemVer:"v2.10.0", GitCommit:"9ad53aac42165a5fadc6c87be0dea6b115f93090", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.10.0", GitCommit:"9ad53aac42165a5fadc6c87be0dea6b115f93090", GitTreeState:"clean"}

Expected result is that the function {{- define "gluu.ldaplist" -}} in _helpers.tpl completes without error even if no values are provided in the array. If there are values provided, the expected string is host:port as output.

If this can be done in another way, I welcome any suggestion.

-- Shammir
gluu
go
kubernetes
kubernetes-helm
templating

1 Answer

8/7/2019

This can be solved with global values which allow values in the parent chart to override (or supply unspecified) values in the child subcharts.

From the Helm docs on Subcharts and Global Values:

  1. A subchart is considered “stand-alone”, which means a subchart can never explicitly depend on its parent chart.
  2. For that reason, a subchart cannot access the values of its parent.
  3. A parent chart can override values for subcharts.
  4. Helm has a concept of global values that can be accessed by all charts.

(At first I didn't think to search for "helm subchart" but once I did an Internet search for that term, this was the first or second result)

Here's a minimal example that solves your issue:

Directory Structure

helm
├── Chart.yaml
├── charts
│   └── chart_a
│       ├── Chart.yaml
│       └── templates
│           └── configMap.yml
├── templates
│   └── _helpers.tpl
└── values.yaml

Note: I added Chart.yaml files to make it actually work, renamed values.yml to values.yaml so that it works by default without extra flags, and removed requirements.yml since it wasn't necessary to reproduce the problem and solution.

values.yaml

global:
  ldap:
    enabled: true
    type: opendj
    extraHosts:
    - host: opendj
      port: 3434
  ldapType: xxx
  ldapPort: 123

The key was to nest what you had under a special global key. Note, I also added ldapType and ldapPort since they were in your _helpers.tpl, and I fixed the YAML structure you had under extraHosts. What was there before didn't actually represent a list of maps with host and port keys. Without this fix, the helm command doesn't fail but doesn't output what you want either.

Result

$ helm template .
---
# Source: helm/charts/chart_a/templates/configMap.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm
data:
  GLUU_LDAP_URL: release-name-xxx:123,opendj:3434
-- Amit Kumar Gupta
Source: StackOverflow