Go Templates - Проверьте, существует ли ключ в списке json
Я использую confd для динамической реконфигурации сервиса nginx и немного борюсь с шаблонами Go. У меня есть объект JSON с именем $data
а также $data.subsets
может содержать ключ с именем 'address' - я хочу выполнять шаблон внутри цикла, только если это условие выполнено.
Я пробовал разные вещи, такие как $data.subsets[0].addresses
Вы видите ниже, что совершенно неправильно. Я не совсем уверен, как это можно сделать правильно.
Это часть моего шаблона nginx, которую я хочу рендерить только в том случае, если есть хотя бы одна вышестоящая служба, а не если ее нет / она недоступна.
Следующий шаблон - это объекты json для $data
на успехе любой провал.
Заранее благодарю за помощь, очень признателен!
{{ range $ns := getvs "/registry/services/endpoints/*/app" }}
{{ $data := json $ns }}
{{ if $data.subsets[0].addresses }}
upstream {{ $data.metadata.namespace }}_{{ $data.metadata.name }}_pool {
{{ range $subset := $data.subsets }}{{ range $ref := $subset.addresses }}{{ range $portConfig := $subset.ports }}
server {{ $ref.ip }}:{{ $portConfig.port }};
{{ end }}{{ end }}{{ end }}
}
{{ end }}
{{ end }}
Пример $data
когда нет запланированных стручков:
{
"kind":"Endpoints",
"apiVersion":"v1",
"metadata":{
"name":"app",
"namespace":"ns1",
"selfLink":"/api/v1/namespaces/ns1/endpoints/app",
"labels":{
"app":"app"
}
},
"subsets":[]
}
Пример $data
когда работают стручки, но они не здоровы:
{
"kind":"Endpoints",
"apiVersion":"v1",
"metadata":{
"name":"app",
"namespace":"ns1",
"labels":{
"app":"app"
}
},
"subsets":[
{
"notReadyAddresses":[
{
"ip":"10.254.60.5",
"targetRef":{
"kind":"Pod",
"namespace":"ns1",
"name":"app-421757659-83rfg",
}
}
],
"ports":[
{
"name":"ns1-app-8080",
"port":8080,
"protocol":"TCP"
}
]
}
]
}
Пример $data
когда есть работающие и доступные стручки. Это единственное условие, которое я хочу выполнить для итерации шаблона для рендеринга.
{
"kind":"Endpoints",
"apiVersion":"v1",
"metadata":{
"name":"app",
"namespace":"ns1",
"selfLink":"/api/v1/namespaces/ns1/endpoints/app",
"labels":{
"app":"app"
}
},
"subsets":[
{
"addresses":[
{
"ip":"10.254.18.11",
"targetRef":{
"kind":"Pod",
"namespace":"ns1",
"name":"app-3869480132-kfthi"
}
},
{
"ip":"10.254.18.9",
"targetRef":{
"kind":"Pod",
"namespace":"ns1",
"name":"app-3869480132-9bufk"
}
}
],
"ports":[
{
"name":"ns1-app-8080",
"port":8080,
"protocol":"TCP"
}
]
}
]
}
1 ответ
$data.subsets[0].addresses
является недопустимым выражением шаблона (содержит [
а также ]
). Попробуйте следующее определение шаблона:
{{range $cfg := getvs "/registry/services/endpoints/*/app"}}
{{$data := json $cfg}}
{{range $data.subsets}}{{range $addr := .addresses}}
{{with $ns := $addr.targetRef.namespace}}
upstream {{$ns}}_{{$addr.targetRef.name}}_pool {
{{range $data.subsets}}{{range $port := .ports}}
{{/*
Split port.name then test if address namespace
match the port.name. Test Condition:
len($portDesc) > 0 && $portDesc[0] == $ns
*/}}
{{$portDesc := split $port.name "-"}}
{{if and (gt (len $portDesc) 0) (eq (index $portDesc 0) $ns)}}
server {{ $addr.ip }}:{{ $port.port }};
{{end}}
{{end}}{{ end }}
}
{{end}}
{{end}}{{end}}
Сгенерированный вывод (после удаления пустых строк) для вышеуказанных трех данных json должен быть:
upstream ns1_app-3869480132-kfthi_pool {
server 10.254.18.11:8080;
}
upstream ns1_app-3869480132-9bufk_pool {
server 10.254.18.9:8080;
}
Ключ range
действие в {{range $data.subsets}}{{range $addr := .addresses}}
, Ничего не будет написано, если len
трубопровода (subsets
или же addresses
) равен нулю, т.е. когда subsets
не содержит элемент или addresses
является null
(элемент подмножеств не назван addresses
).