在 helm 中迭代 YAML 复杂映射
Iterate over a YAML complex map in helm
我正在使用 Helm
v3 并尝试在具有以下内容的 Kubernetes 网络策略的 YAML 定义文件中迭代复杂的 object/map:
values.yaml:
networkPolicies:
egress:
- service: microservice-name
destination:
- podLabels:
app=microservice-name
namespaceLabels:
company.com/microservices: microservice-name
protocol: TCP
ports:
- 8444
在k8s定义文件中,我有这样的代码:
egress-networkpolicy.yaml:
{{- range $v, $rule := .Values.networkPolicies.egress }}---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-kong-to-{{ $rule.service }}-egress
namespace: kong
annotations:
description: Kong egress policies
spec:
podSelector:
matchLabels:
{{- range $label,$value := $rule.podSelector }}
{{ $label }}: {{ $value }}
{{- end }}
egress:
- to:
{{- range $from := $rule.to }}
- podSelector:
matchLabels:
{{- range $label,$value := $from.podLabels }}
{{ $label }}: {{ $value }}
{{- end }}
{{- if has $from "namespaceLabels" }}
namespaceSelector:
{{- if eq ( len $from.namespaceLabels ) 0 }} {}
{{- else }}
matchLabels:
{{- range $label,$value := $from.namespaceLabels }}
{{ $label }}: {{ $value }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if has $rule "ports" }}
ports:
{{- range $port := $rule.service.ports }}
- protocol: {{ $port.protocol }}
- port: {{ $port }}
{{- end }}
{{- end }}
policyTypes:
- Egress
{{ end -}}
不幸的是,当我 运行 helm template name-of-the-template
它抛出以下错误:
❯ helm template name-of-the-template --debug
install.go:178: [debug] Original chart version: ""ate name-of-the-template --debug
install.go:199: [debug] CHART PATH: /Users/user/charts/name-of-the-template
Error: template: name-of-the-template/templates/egress-networkpolicy.yaml:34:13: executing "name-of-the-template/templates/egress-networkpolicy.yaml" at <has $rule "ports">: error calling has: Cannot find has on type string
helm.go:88: [debug] template: name-of-the-template/templates/egress-networkpolicy.yaml:34:13: executing "name-of-the-template/templates/egress-networkpolicy.yaml" at <has $rule "ports">: error calling has: Cannot find has on type string
我找不到 Helm
在该行抛出此错误的原因,但在该行之前的类似代码中找不到。
改为has
template function checks for membership in a list. In this context $rule
is a mapping or dictionary (it is one of the items in the list under egress
) and for that type you need to use hasKey
。
{{- if hasKey $rule "ports" }}{{/* hasKey, not has */}}
ports:
...
{{- end }}
可以稍微简化这一点的一件事是在这里使用 Go 模板 with
构造而不是 if
。 with
的作用与 if
相同,除了它还会将特殊变量 .
重新绑定到条件值(如果它为真)。访问映射中未定义的键是可以的,但是 returns nil
,这是错误的。所以在这种情况下我可能会写
{{- with $rule.ports }}
ports:
{{- range . }}
- protocol: {{ $rule.protocol }}
port: {{ . }}
{{- end }}
{{- end }}
(但请注意,正如我所写的那样,第三行和第五行中的 .
是不同的变量,并且这种用法也会更改 .
,如出现在 .Values
或 template "name" .
在这个不会成为实际问题的小循环中。)
我正在使用 Helm
v3 并尝试在具有以下内容的 Kubernetes 网络策略的 YAML 定义文件中迭代复杂的 object/map:
values.yaml:
networkPolicies:
egress:
- service: microservice-name
destination:
- podLabels:
app=microservice-name
namespaceLabels:
company.com/microservices: microservice-name
protocol: TCP
ports:
- 8444
在k8s定义文件中,我有这样的代码:
egress-networkpolicy.yaml:
{{- range $v, $rule := .Values.networkPolicies.egress }}---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-kong-to-{{ $rule.service }}-egress
namespace: kong
annotations:
description: Kong egress policies
spec:
podSelector:
matchLabels:
{{- range $label,$value := $rule.podSelector }}
{{ $label }}: {{ $value }}
{{- end }}
egress:
- to:
{{- range $from := $rule.to }}
- podSelector:
matchLabels:
{{- range $label,$value := $from.podLabels }}
{{ $label }}: {{ $value }}
{{- end }}
{{- if has $from "namespaceLabels" }}
namespaceSelector:
{{- if eq ( len $from.namespaceLabels ) 0 }} {}
{{- else }}
matchLabels:
{{- range $label,$value := $from.namespaceLabels }}
{{ $label }}: {{ $value }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if has $rule "ports" }}
ports:
{{- range $port := $rule.service.ports }}
- protocol: {{ $port.protocol }}
- port: {{ $port }}
{{- end }}
{{- end }}
policyTypes:
- Egress
{{ end -}}
不幸的是,当我 运行 helm template name-of-the-template
它抛出以下错误:
❯ helm template name-of-the-template --debug
install.go:178: [debug] Original chart version: ""ate name-of-the-template --debug
install.go:199: [debug] CHART PATH: /Users/user/charts/name-of-the-template
Error: template: name-of-the-template/templates/egress-networkpolicy.yaml:34:13: executing "name-of-the-template/templates/egress-networkpolicy.yaml" at <has $rule "ports">: error calling has: Cannot find has on type string
helm.go:88: [debug] template: name-of-the-template/templates/egress-networkpolicy.yaml:34:13: executing "name-of-the-template/templates/egress-networkpolicy.yaml" at <has $rule "ports">: error calling has: Cannot find has on type string
我找不到 Helm
在该行抛出此错误的原因,但在该行之前的类似代码中找不到。
改为has
template function checks for membership in a list. In this context $rule
is a mapping or dictionary (it is one of the items in the list under egress
) and for that type you need to use hasKey
。
{{- if hasKey $rule "ports" }}{{/* hasKey, not has */}}
ports:
...
{{- end }}
可以稍微简化这一点的一件事是在这里使用 Go 模板 with
构造而不是 if
。 with
的作用与 if
相同,除了它还会将特殊变量 .
重新绑定到条件值(如果它为真)。访问映射中未定义的键是可以的,但是 returns nil
,这是错误的。所以在这种情况下我可能会写
{{- with $rule.ports }}
ports:
{{- range . }}
- protocol: {{ $rule.protocol }}
port: {{ . }}
{{- end }}
{{- end }}
(但请注意,正如我所写的那样,第三行和第五行中的 .
是不同的变量,并且这种用法也会更改 .
,如出现在 .Values
或 template "name" .
在这个不会成为实际问题的小循环中。)