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).

Другие вопросы по тегам