ory / k8s

Kubernetes Helm Charts for the ORY ecosystem.
https://k8s.ory.sh/helm
Apache License 2.0
334 stars 259 forks source link

Kratos chart: nil pointer evaluating interface {}.configmap when using example emailTemplates #490

Closed varac closed 2 years ago

varac commented 2 years ago

Preflight checklist

Describe the bug

I am trying to use the example kratos.emailTemplates with chart v0.25.0. But when I try to template the chart locally I get this:

❯ helm -n test template kratos-test . 
Error: template: kratos/templates/statefulset-mail.yaml:43:12: executing "kratos/templates/statefulset-mail.yaml" at <include "kratos.annotations.checksum" .>: error calling include: template: kratos/templates/_helpers.tpl:178:30: executing "kratos.annotations.checksum" at <include (print $.Template.BasePath "/configmap-templates.yaml") .>: error calling include: template: kratos/templates/configmap-templates.yaml:13:20: executing "kratos/templates/configmap-templates.yaml" at <.Values.configmap.annotations>: nil pointer evaluating interface {}.configmap

Btw. the kratos.emailTemplates key is not properly rendered by helm docs, it doesn't show up in the README.md table in the first column, but in the last one under kratos.config. I'm happy to provide a simple fix for this later)

Reproducing the bug

Steps to reproduce:

  1. Comment out the kratos.emailTemplates key in values.yaml and fix the indentation
❯ git diff                                                   
diff --git a/helm/charts/kratos/values.yaml b/helm/charts/kratos/values.yaml
index 4df964e..7816828 100644
--- a/helm/charts/kratos/values.yaml
+++ b/helm/charts/kratos/values.yaml
@@ -112,7 +112,7 @@ kratos:
     # -- Configure the way to execute database migration. Possible values: job, initContainer
     # When set to job, the migration will be executed as a job on release or upgrade.
     # When set to initContainer, the migration will be executed when kratos pod is created
-    # Defaults to job  
+    # Defaults to job
     type: job

   # -- You can add multiple identity schemas here
@@ -131,34 +131,37 @@ kratos:
   #  Note: If you are setting config.courier.template_override_path you need to supply overrides for all templates.
   #        It is currently not possible to overrides only selected methods.
   #
-  #  emailTemplates:
-  #    recovery:
-  #      valid:
-  #        subject: Recover access to your account
-  #        body: |-
-  #          Hi, please recover access to your account by clicking the following link:
-  #
-  #          <a href="{{ .RecoveryURL }}">{{ .RecoveryURL }}</a>
-  #        plainBody: Hi, please recover access to your account by clicking the following link: {{ .RecoveryURL }}
-  #      invalid:
-  #        subject: Account access attempted
-  #        body: |-
-  #          Hi, you (or someone else) entered this email address when trying to recover access to an account.
-  #
-  #          However, this email address is not on our database of registered users and therefore the attempt has failed. If this was you, check if you signed up using a different address. If this was not you, please ignore this email.
-  #        plainBody: Hi, you (or someone else) entered this email address when trying to recover access to an account.
-  #    verification:
-  #      valid:
-  #        subject: Please verify your email address
-  #        body: |-
-  #          Hi, please verify your account by clicking the following link:
-  #
-  #          <a href="{{ .VerificationURL }}">{{ .VerificationURL }}</a>
-  #        plainBody: Hi, please verify your account by clicking the following link: {{ .VerificationURL }}
-  #      invalid:
-  #        subject:
-  #        body:
-  #        plainBody:
+  emailTemplates:
+    recovery:
+      valid:
+        subject: Recover access to your account
+        body: |-
+          Hi, please recover access to your account by clicking the following link:
+
+          <a href="{{ .RecoveryURL }}">{{ .RecoveryURL }}</a>
+        plainBody: |-
+          Hi, please recover access to your account by clicking the following link: {{ .RecoveryURL }}
+      invalid:
+        subject: Account access attempted
+        body: |-
+          Hi, you (or someone else) entered this email address when trying to recover access to an account.
+
+          However, this email address is not on our database of registered users and therefore the attempt has failed. If this was you, check if you signed up using a different address. If this was not you, please ignore this email.
+        plainBody: |-
+          Hi, you (or someone else) entered this email address when trying to recover access to an account.
+    verification:
+      valid:
+        subject: Please verify your email address
+        body: |-
+          Hi, please verify your account by clicking the following link:
+
+          <a href="{{ .VerificationURL }}">{{ .VerificationURL }}</a>
+        plainBody: |-
+          Hi, please verify your account by clicking the following link: {{ .VerificationURL }}
+      invalid:
+        subject:
+        body:
+        plainBody:
  1. Locally template the chart:
❯ helm -n test template kratos-test . 

Relevant log output

❯ helm -n test template kratos-test . 

Error: template: kratos/templates/statefulset-mail.yaml:43:12: executing "kratos/templates/statefulset-mail.yaml" at <include "kratos.annotations.checksum" .>: error calling include: template: kratos/templates/_helpers.tpl:178:30: executing "kratos.annotations.checksum" at <include (print $.Template.BasePath "/configmap-templates.yaml") .>: error calling include: template: kratos/templates/configmap-templates.yaml:13:20: executing "kratos/templates/configmap-templates.yaml" at <.Values.configmap.annotations>: nil pointer evaluating interface {}.configmap

### Relevant configuration

```yml
# Default values for kratos.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# -- Number of replicas in deployment
replicaCount: 1
# -- Deployment update strategy
strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 30%
    maxUnavailable: 0

image:
  # -- ORY KRATOS image
  repository: oryd/kratos
  # -- ORY KRATOS VERSION
  # Alternative format: image: oryd/kratos:v0.6.3-alpha.1
  tag: v0.10.1
  pullPolicy: IfNotPresent
  # imagePullPolicy: Always

imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""

service:
  admin:
    enabled: true
    type: ClusterIP
    port: 80
    # -- The service port name. Useful to set a custom service port name if it must follow a scheme (e.g. Istio)
    name: http
    # -- Provide custom labels. Use the same syntax as for annotations.
    labels: {}
    # -- If you do want to specify annotations, uncomment the following
    # lines, adjust them as necessary, and remove the curly braces after 'annotations:'.
    annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"
  public:
    enabled: true
    type: ClusterIP
    port: 80
    # -- The service port name. Useful to set a custom service port name if it must follow a scheme (e.g. Istio)
    name: http
    # -- Provide custom labels. Use the same syntax as for annotations.
    labels: {}
    # -- If you do want to specify annotations, uncomment the following
    # lines, adjust them as necessary, and remove the curly braces after 'annotations:'.
    annotations: {}
    # kubernetes.io/ingress.class: nginx
    # kubernetes.io/tls-acme: "true"

secret:
  # -- switch to false to prevent creating the secret
  enabled: true
  # -- Provide custom name of existing secret, or custom name of secret to be created
  nameOverride: ""
  # nameOverride: "myCustomSecret"
  # -- Annotations to be added to secret. Annotations are added only when secret is being created. Existing secret will not be modified.
  secretAnnotations:
    # Create the secret before installation, and only then. This saves the secret from regenerating during an upgrade
    # pre-upgrade is needed to upgrade from 0.7.0 to newer. Can be deleted afterwards.
    helm.sh/hook-weight: "0"
    helm.sh/hook: "pre-install, pre-upgrade"
    helm.sh/hook-delete-policy: "before-hook-creation"
    helm.sh/resource-policy: "keep"
  # -- switch to false to prevent checksum annotations being maintained and propogated to the pods
  hashSumEnabled: true

ingress:
  admin:
    enabled: false
    className: ""
    annotations:
      {}
      # kubernetes.io/ingress.class: nginx
      # kubernetes.io/tls-acme: "true"
    hosts:
      - host: kratos.admin.local.com
        paths:
          - path: /
            pathType: ImplementationSpecific
    tls: []
    #  - secretName: chart-example-tls
    #    hosts:
    #      - chart-example.local
  public:
    enabled: false
    className: ""
    annotations:
      {}
      # kubernetes.io/ingress.class: nginx
      # kubernetes.io/tls-acme: "true"
    hosts:
      - host: kratos.public.local.com
        paths:
          - path: /
            pathType: ImplementationSpecific
    tls: []
    #  - secretName: chart-example-tls
    #    hosts:
    #      - chart-example.local

kratos:
  development: false
  # -- Enable the initialization job. Required to work with a DB

  # -- Enables database migration
  automigration:
    enabled: false
    # -- Configure the way to execute database migration. Possible values: job, initContainer
    # When set to job, the migration will be executed as a job on release or upgrade.
    # When set to initContainer, the migration will be executed when kratos pod is created
    # Defaults to job
    type: job

  # -- You can add multiple identity schemas here
  identitySchemas: {}
  # identitySchemas:
  #  "identity.default.schema.json": |
  #    {
  #      // ...
  #    }
  #  "identity.email.schema.json": |
  #    {
  #      // ...
  #    }

  # -- You can customize the emails kratos is sending (also uncomment config.courier.template_override_path below)
  #  Note: If you are setting config.courier.template_override_path you need to supply overrides for all templates.
  #        It is currently not possible to overrides only selected methods.
  #
  emailTemplates:
    recovery:
      valid:
        subject: Recover access to your account
        body: |-
          Hi, please recover access to your account by clicking the following link:

          <a href="{{ .RecoveryURL }}">{{ .RecoveryURL }}</a>
        plainBody: |-
          Hi, please recover access to your account by clicking the following link: {{ .RecoveryURL }}
      invalid:
        subject: Account access attempted
        body: |-
          Hi, you (or someone else) entered this email address when trying to recover access to an account.

          However, this email address is not on our database of registered users and therefore the attempt has failed. If this was you, check if you signed up using a different address. If this was not you, please ignore this email.
        plainBody: |-
          Hi, you (or someone else) entered this email address when trying to recover access to an account.
    verification:
      valid:
        subject: Please verify your email address
        body: |-
          Hi, please verify your account by clicking the following link:

          <a href="{{ .VerificationURL }}">{{ .VerificationURL }}</a>
        plainBody: |-
          Hi, please verify your account by clicking the following link: {{ .VerificationURL }}
      invalid:
        subject:
        body:
        plainBody:

  config:
    courier:
      smtp: {}
      #template_override_path: /conf/courier-templates

    serve:
      public:
        port: 4433
      admin:
        port: 4434

    secrets: {}

# -- Configuration options for the k8s deployment
deployment:
  # -- Configure the livenessProbe parameters
  livenessProbe:
    initialDelaySeconds: 30
    periodSeconds: 10
    failureThreshold: 5
  # -- Configure the readinessProbe parameters
  readinessProbe:
    initialDelaySeconds: 30
    periodSeconds: 10
    failureThreshold: 5

  # -- Configure a custom livenessProbe. This overwrites the default object
  customLivenessProbe: {}
  # -- Configure a custom readinessProbe. This overwrites the default object
  customReadinessProbe: {}

  # -- Array of extra arguments to be passed down to the deployment. Kubernetes args format is expected
  # - --foo
  # - --sqa-opt-out
  extraArgs: []

  # -- Array of extra envs to be passed to the deployment. Kubernetes format is expected
  # - name: FOO
  #   value: BAR
  extraEnv: []
  # -- If you want to mount external volume
  # For example, mount a secret containing Certificate root CA to verify database
  # TLS connection.
  extraVolumes: []
  # - name: my-volume
  #   secret:
  #     secretName: my-secret
  extraVolumeMounts: []
  # - name: my-volume
  #   mountPath: /etc/secrets/my-secret
  #   readOnly: true

  # extraVolumes:
  #   - name: postgresql-tls
  #     secret:
  #       secretName: postgresql-root-ca
  # extraVolumeMounts:
  #   - name: postgresql-tls
  #     mountPath: "/etc/postgresql-tls"
  #     readOnly: true

  # -- If you want to add extra init containers. These are processed before the migration init container.
  extraInitContainers: {}
  # extraInitContainers: |
  #  - name: ...
  #    image: ...

  # -- If you want to add extra sidecar containers.
  extraContainers: {}
  # extraContainers: |
  #  - name: ...
  #    image: ...

  # -- Configuration for tracing providers. Only datadog is currently supported through this block.
  # If you need to use a different tracing provider, please manually set the configuration values
  # via "kratos.config" or via "deployment.extraEnv".
  tracing:
    datadog:
      enabled: false

      # Sets the datadog DD_ENV environment variable. This value indicates the environment where kratos is running.
      # Default value: "none".
      # env: production

      # Sets the datadog DD_VERSION environment variable. This value indicates the version that kratos is running.
      # Default value: .Values.image.tag (i.e. the tag used for the docker image).
      # version: X.Y.Z

      # Sets the datadog DD_SERVICE environment variable. This value indicates the name of the service running.
      # Default value: "ory/kratos".
      # service: ory/kratos

      # Sets the datadog DD_AGENT_HOST environment variable. This value indicates the host address of the datadog agent.
      # If set to true, this configuration will automatically set DD_AGENT_HOST to the field "status.hostIP" of the pod.
      # Default value: false.
      # useHostIP: true

  resources: {}
  #  We usually recommend not to specify default resources and to leave this as a conscious
  #  choice for the user. This also increases chances charts run on environments with little
  #  resources, such as Minikube. If you do want to specify resources, uncomment the following
  #  lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  #  limits:
  #    cpu: 100m
  #    memory: 128Mi
  #  requests:
  #    cpu: 100m
  #  memory: 128Mi

  # -- Node labels for pod assignment.
  nodeSelector: {}
  # If you do want to specify node labels, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'nodeSelector:'.
  #   foo: bar

  # -- Configure node tolerations.
  tolerations: []

  labels: {}
  #      If you do want to specify additional labels, uncomment the following
  #      lines, adjust them as necessary, and remove the curly braces after 'labels:'.
  #      e.g.  type: app

  annotations: {}
  #      If you do want to specify annotations, uncomment the following
  #      lines, adjust them as necessary, and remove the curly braces after 'annotations:'.
  #      e.g.  sidecar.istio.io/rewriteAppHTTPProbers: "true"

  # -- The secret specified here will be used to load environment variables with envFrom.
  # This allows arbitrary environment variables to be provided to the application which is useful for
  # sensitive values which should not be in a configMap.
  # This secret is not created by the helm chart and must already exist in the namespace.
  # https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/#configure-all-key-value-pairs-in-a-secret-as-container-environment-variables
  # environmentSecretsName:

  # -- Specify the serviceAccountName value.
  # In some situations it is needed to provide specific permissions to Kratos deployments.
  # Like for example installing Kratos on a cluster with a PosSecurityPolicy and Istio.
  # Uncomment if it is needed to provide a ServiceAccount for the Kratos deployment.
  serviceAccount:
    # -- Specifies whether a service account should be created
    create: true
    # -- Annotations to add to the service account
    annotations: {}
    # -- The name of the service account to use. If not set and create is true, a name is generated using the fullname template
    name: ""

  # https://github.com/kubernetes/kubernetes/issues/57601
  automountServiceAccountToken: true

## -- Configuration options for the k8s statefulSet
statefulSet:
  resources: {}
  #  We usually recommend not to specify default resources and to leave this as a conscious
  #  choice for the user. This also increases chances charts run on environments with little
  #  resources, such as Minikube. If you do want to specify resources, uncomment the following
  #  lines, adjust them as necessary, and remove the curly braces after 'resources:'.
  #  limits:
  #    cpu: 100m
  #    memory: 128Mi
  #  requests:
  #    cpu: 100m
  #  memory: 128Mi

  # -- Array of extra arguments to be passed down to the StatefulSet. Kubernetes args format is expected
  extraArgs: []
  # - --foo
  # - --sqa-opt-out

  extraEnv: []
  # -- If you want to mount external volume
  # For example, mount a secret containing Certificate root CA to verify database
  # TLS connection.
  extraVolumes: []
  # - name: my-volume
  #   secret:
  #     secretName: my-secret
  extraVolumeMounts: []
  # - name: my-volume
  #   mountPath: /etc/secrets/my-secret
  #   readOnly: true

  # -- If you want to add extra init containers. These are processed before the migration init container.
  extraInitContainers: {}
  # extraInitContainers: |
  #  - name: ...
  #    image: ...

  # -- If you want to add extra sidecar containers.
  extraContainers: {}
  # extraContainers: |
  #  - name: ...
  #    image: ...

  annotations: {}
  #      If you do want to specify annotations, uncomment the following
  #      lines, adjust them as necessary, and remove the curly braces after 'annotations:'.
  #      e.g.  sidecar.istio.io/rewriteAppHTTPProbers: "true"

  labels: {}
  #      If you do want to specify additional labels, uncomment the following
  #      lines, adjust them as necessary, and remove the curly braces after 'labels:'.
  #      e.g.  type: app

  # -- Node labels for pod assignment.
  nodeSelector: {}
  # If you do want to specify node labels, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'nodeSelector:'.
  #   foo: bar

  log:
    format: json
    level: trace

securityContext:
  capabilities:
    drop:
      - ALL
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  runAsUser: 100
  allowPrivilegeEscalation: false
  privileged: false

# -- Horizontal pod autoscaling configuration
autoscaling:
  enabled: false
  minReplicas: 1
  maxReplicas: 3
  targetCPUUtilizationPercentage: 80
  # targetMemoryUtilizationPercentage: 80

# -- Values for initialization job
job:
  # -- If you do want to specify annotations, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'annotations:'.
  annotations: {}
  # kubernetes.io/ingress.class: nginx
  # kubernetes.io/tls-acme: "true"

  # -- If you want to add extra sidecar containers.
  extraContainers: {}
  # extraContainers: |
  #  - name: ...
  #    image: ...

  # -- Node labels for pod assignment.
  nodeSelector: {}
  # If you do want to specify node labels, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'nodeSelector:'.
  #   foo: bar

  # -- If you want to add lifecycle hooks.
  lifecycle: {}
  # lifecycle: |
  #   preStop:
  #     exec:
  #       command: [...]

  # -- Set automounting of the SA token
  automountServiceAccountToken: true

  # -- Set sharing process namespace
  shareProcessNamespace: false

  # -- Specify the serviceAccountName value.
  # In some situations it is needed to provides specific permissions to Hydra deployments
  # Like for example installing Hydra on a cluster with a PosSecurityPolicy and Istio.
  # Uncoment if it is needed to provide a ServiceAccount for the Hydra deployment.
  serviceAccount:
    # -- Specifies whether a service account should be created
    create: true
    # -- Annotations to add to the service account
    annotations:
      helm.sh/hook-weight: "0"
      helm.sh/hook: "pre-install, pre-upgrade"
      helm.sh/hook-delete-policy: "before-hook-creation"
    # -- The name of the service account to use. If not set and create is true, a name is generated using the fullname template
    name: ""

  spec:
    # -- Set job back off limit
    backoffLimit: 10

# -- Configure node affinity
affinity: {}
# -- Node labels for pod assignment.
nodeSelector: {}
# -- If you do want to specify node labels, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'annotations:'.
#   foo: bar
# Configure node tolerations.
tolerations: []

# -- Configuration of the watcher sidecar
watcher:
  enabled: false
  image: oryd/k8s-toolbox:0.0.4
  mountFile: ""
  # mountFile: /etc/secrets/my-secret/foo

# -- PodDistributionBudget configuration
pdb:
  enabled: false
  spec:
    minAvailable: 1

# -- Parameters for the Prometheus ServiceMonitor objects.
# Reference: https://docs.openshift.com/container-platform/4.6/rest_api/monitoring_apis/servicemonitor-monitoring-coreos-com-v1.html
serviceMonitor:
  # -- switch to false to prevent creating the ServiceMonitor
  enabled: true
  # -- HTTP scheme to use for scraping.
  scheme: http
  # -- Interval at which metrics should be scraped
  scrapeInterval: 60s
  # -- Timeout after which the scrape is ended
  scrapeTimeout: 30s
  # -- Provide additionnal labels to the ServiceMonitor ressource metadata
  labels: {}
  # -- TLS configuration to use when scraping the endpoint
  tlsConfig: {}

configmap:
  # -- switch to false to prevent checksum annotations being maintained and propogated to the pods
  hashSumEnabled: true
  # -- If you do want to specify annotations for configmap, uncomment the following
  # lines, adjust them as necessary, and remove the curly braces after 'annotations:'.
  annotations: {}

Version

Kratos chart 0.25.0

On which operating system are you observing this issue?

Linux

In which environment are you deploying?

Kubernetes with Helm

Additional Context

No response

Demonsthere commented 2 years ago

All of because of a missing context switch character 😅

varac commented 2 years ago

@Demonsthere Thanks for fixing, do you mind releasing version to fix the helm chart ?

Demonsthere commented 2 years ago

Hey, sure thing, will do probably later today ;)