2016-10-07 21 views
0

我正在使用confd進行動態nginx服務重新配置,並且與Go模板有點糾結。我有一個名爲$data的json對象,並且$data.subsets可能包含一個名爲'addresses'的鍵 - 我只想在滿足條件時執行循環內的模板。轉到模板 - 檢查一個鍵是否存在於json列表中

我試過了各種東西,如你在下面看到的$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如果有運行中的豆莢,但沒有健康:

$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" 
      } 
     ] 
     } 
    ] 
} 

當有豆莢運行並可用。這是我希望滿足迭代模板渲染的唯一條件。

{ 
    "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" 
      } 
     ] 
     } 
    ] 
} 
+0

爲什麼你不檢查正常的JSON處理正常的代碼中的條件,然後只傳遞一個布爾到模板?在你的json中訪問值是非常直接的,不管它是哪種變化,但我不確定你會怎麼做,因爲在這種情況下庫的發揮。除非'$ data'對象在其他地方大量使用,否則我認爲它不應該傳遞給模板,因爲大部分對象在這種情況下是無關緊要的。事實上,你應該只是提取地址列表並傳遞它,並且在你的模板中沒有這個邏輯。 – evanmcdonnal

回答

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 $data.subsets}}{{range $addr := .addresses}}range動作。如果管道(subsetsaddresses)的len爲零,即當subsets不包含元素或addressesnull(命名爲addresses沒有亞元),什麼都不會寫。

相關問題