首页 > 解决方案 > 如果索引不存在如何使用默认值

问题描述

我有以下输入:

alerts:
  api_http_500:
    default_config:
      enabled: true
    override:
      user_1:
        enabled: false

我想检查用户是否存在启用的字段。如果不是这样,我使用默认的。我正在使用索引default如下所示:

{{ (index $alerts "alerts" "api_http_500" "override" "user_2" "enabled") | default (index $alerts "alerts" "api_http_500" "default_config" "enabled") }}

但我有这个错误<index $alerts "alerts" "user_2" "enabled">: error calling index: index of nil pointer

我不知道如何在没有 if/else 结构的情况下使用默认值。

标签: kubernetes-helmgo-templates

解决方案


根本错误是数据中没有user_2字段,因此当您尝试获取它时,您会得到nil; 你不能在其中进行更深入的查找。 default还是可以来救援的!

Gotext/template语言支持局部变量。所以我们可以将一个局部变量设置为应该是什么user_2值。如果不存在,Sprig支持库包含一个dict可以生成空字典的函数。

{{- $overrides := index $alerts "user_2" | default dict -}}

Now$overrides始终是字典,因此我们可以在其中查找,或者如果那里没有任何内容,则回退到默认值。

{{- $a := index $alerts.alerts "api_http_500" -}}
{{- $defaults := $a.default_config -}}
{{- $overrides := index $a.override "user_2" | default dict -}}
{{- $enabled := $overrides.enabled | default $defaults.enabled -}}

这看起来不错,但另一个问题是default不能区分存在但假和不存在。两者都是“假的”,将被替换为默认值。标准模板eq要求值具有相同的类型,但 SprigdeepEqual没有此要求。

This lets you write the detailed logical statement that the option should be enabled if the override is true, or if the override is not false (I don't think there's a way to spell out "nil" or "absent") and the default is true.

{{- $enabled := or $overrides.enabled (and (not (deepEqual $overrides.enabled false)) $defaults.enabled) -}}

(It is worth considering whether you want this much Go template logic, and whether you can either restructure your values file to simplify this, or use something like a Kubernetes operator that's in a more normal language and is more testable.)


推荐阅读