0

動的なnginxサービスの再構成にconfdを使用しており、Goテンプレートと少し苦労しています。という名前の json オブジェクトが$dataあり$data.subsets、「addresses」という名前のキーが含まれている可能性があります。その条件が満たされた場合にのみ、ループ内でテンプレートを実行したいと考えています。

以下に示すようなさまざまなことを試しましたが、$data.subsets[0].addressesこれは完全に間違っています。これを正しく行う方法がよくわかりません。

これは、少なくとも 1 つのアップストリーム サービスがある場合にのみレンダリングしたい nginx テンプレートの一部であり、サービスがない場合や利用できない場合ではありません。

テンプレートに続くのは、$data成功した場合と失敗した場合の json オブジェクトです。

事前に助けてくれてありがとう、それは大歓迎です!

{{ 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 }}

$dataPod がスケジュールされていない場合の例:

{  
   "kind":"Endpoints",
   "apiVersion":"v1",
   "metadata":{  
      "name":"app",
      "namespace":"ns1",
      "selfLink":"/api/v1/namespaces/ns1/endpoints/app",
      "labels":{  
         "app":"app"
      }
   },
   "subsets":[]
}

$dataPod が実行されているが正常ではない場合の例:

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

1 に答える 1

2

$data.subsets[0].addresses不正なテンプレート式です ( [and を含みます])。次のテンプレート定義を試してください。

{{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}}

上記の 3 つの 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含まれていないか( という名前のサブセット要素がない) の場合は、何も書き込まれません。 addressesnulladdresses

于 2016-10-08T03:54:06.390 に答える