Le modèle Helm n'est pas compatible avec la structure values.yaml

Aug 16 2020

J'ai le fichier ingress.yaml suivant :

spec:
{{- if .Values.ingress.tls }}
  tls:
  {{- range .Values.ingress.tls }}
    - hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
      secretName: {{ .secretName }}
  {{- end }}
{{- end }}
  rules:
  {{- range .Values.ingress.hosts }}
    - host: {{ .host }}                 // row 31
      http:
        paths:
        {{- range .paths }}
          - path: {{ . | quote }}
            backend:
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
        {{- end }}
  {{- end }}
{{- end }}

Et les valeurs suivantes pour alimenter ce template :

  hosts:
    host: "app.example.com"
    paths:
      - "/api"
      - "/oauth"

  tls:
    - secretName: "example-tls"
      hosts:
        - "*.app.example.com"
        - "dev.example.com"

Lorsque je lance "helm install", il échoue sur:

Erreur : ÉCHEC DE LA MISE À NIVEAU : modèle : modèles/ingress.yaml:31:15 : exécution de "templates/ingress.yaml" sur <.host> : impossible d'évaluer l'hôte de champ dans l'interface de type {}

Donc, pour moi, il semble que les hôtes doivent être une liste, pas un dictionnaire (à cause de l'instruction de plage ). Alors je le convertis :

  hosts:
    - host: "app.example.com"
      paths:
        - "/api"
        - "/oauth"

Mais dans ce cas j'obtiens :

avertissement : la destination des hôtes est une table. Ignorer la valeur non tabulaire [map[host:app.example.com paths:[/api /oauth]]]

et la même erreur que ci-dessus en plus.

Comment le faire fonctionner ?

MISE À JOUR 1

Valeurs:

ingress:
  enabled: true

  rules:
    - host: c1.app.example.com
      paths:
        - /api
        - /oauth
    - host: c2.app.example.com
      paths:
        - /api
        - /oauth
  tls:
    - secretName: "example-tls"
      hosts:
        - "*.app.example.com"
        - "dev.example.com"

Modèle:

{{- if .Values.ingress.tls }}
  tls:
  {{- range .Values.ingress.tls }}
    - hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
      secretName: {{ .secretName }}
  {{- end }}
{{- end }}
  rules:
  {{- range .Values.ingress.rules }}
    - host: {{ .host | quote }}
      http:
        paths:
        {{- range .paths }}
          - path: {{ . | quote }}
            backend:
              serviceName: {{ $fullName }}
              servicePort: {{ $svcPort }}
        {{- end }}
  {{- end }}
{{- end }}

MISE À JOUR 2

J'ai compris que le problème n'était pas dans le code mais dans la ligne de commande. J'ai alimenté avec une chaîne au lieu d'un tableau.

modèle helm ... --set ingress.hosts.host=c1.app.example.com ...

Je vais essayer de comprendre comment fournir plusieurs valeurs et les mettre à jour ici.

MISE À JOUR 3

J'ai effacé les données des valeurs :

ingress:
  enabled: false

  rules:
    - host:

  tls:
    - secretName:
      hosts: []

Réponses

1 seshadri_c Aug 16 2020 at 15:36

Le modèle recherche .Values.ingress.hosts, alors que dans vos valeurs affichées, il n'y a pas de ingresspréfixe. Et comme l' rangeopérateur est utilisé, nous devrions avoir une liste de dictionnaire .

De plus, avant de faire un helm install, il serait bon de s'exécuter helm templatejuste pour s'assurer que les définitions YAML sont rendues correctement.

Considérant le contenu ci-dessous dansvalues.yaml :

--- 
ingress: 
  hosts: 
    - 
      host: app1.example.com
      paths: 
        - /api
        - /oauth
    - 
      host: app2.example.com
      paths: 
        - /api1
        - /authz
  tls:
    - hosts:
      - "*.app.example.com"
      - "dev.example.com"
      secretName: "example-tls"

L'exécution de la helm templatecommande donne (j'ai défini serviceNamecomme haproxy et servicePortcomme 8080 pour illustration):

spec:
  tls:
    - hosts:
        - "*.app.example.com"
        - "dev.example.com"
      secretName: example-tls
  rules:
    - host: app1.example.com                 // row 31
      http:
        paths:
          - path: "/api"
            backend:
              serviceName: haproxy
              servicePort: 8080
          - path: "/oauth"
            backend:
              serviceName: haproxy
              servicePort: 8080
    - host: app2.example.com                 // row 31
      # similar output for app2.example.com

1 MichaelA. Aug 27 2020 at 00:13

Répondre à ma propre question.

Le problème résidait dans la non-concordance de la structure du modèle d'entrée et des arguments de ligne de commande que j'ai fournis pour le remplacement des paramètres.

C'est le bon ajustement des arguments de ligne de commande :

helm upgrade <some other options here>
--values ./values.yaml
--set ingress.enabled=True
--set ingress.tls[0].hosts[0]=app.example.com
--set ingress.tls[0].secretName=example-tls
--set ingress.rules[0].host=app.example.com

Cela remplit values.yaml :

ingress:
  enabled: false

  rules:
    - host:

  tls:
    - secretName:
      hosts: []

Pour le modèle d' entrée :

spec:
{{- if .Values.ingress.tls }}
  tls:
  {{- range .Values.ingress.tls }}
    - secretName: {{ .secretName }}
      hosts:
      {{- range .hosts }}
        - {{ . | quote }}
      {{- end }}
  {{- end }}
{{- end }}
  rules:
  {{- range .Values.ingress.rules }}
    - host: {{ .host | quote }}
      http:
        paths:
        - path: /api
          backend:
            serviceName: {{ $fullName }}
            servicePort: {{ $svcPort }}
  {{- end }}
{{- end }}