web-dev-qa-db-ja.com

bashでYAMLファイルからネストされた変数を解析する

このリンク の複雑な.yamlファイルを、Amazon Linux 2のEC2インスタンスで実行されている自動化プログラムの一部として実行されるbashスクリプトにフィードする必要があります。上のリンクの.yamlファイルには、多くのオブジェクト、およびファイルで定義されている多くのオブジェクトの1つで定義されている環境変数の1つを抽出する必要があります。

具体的には、192.168.0.0/16変数のCALICO_IPV4POOL_CIDR値をbash変数に抽出するにはどうすればよいですか?

        - name: CALICO_IPV4POOL_CIDR
          value: "192.168.0.0/16"

よりフラットで単純な.yamlファイルの解析に関する他の投稿やブログエントリをたくさん読んだことがありますが、この質問でCALICO_IPV4POOL_CIDRvalueのようなネストされた値を抽出する方法を示す例は他にありません。

5
CodeMed

そこでは2つの問題があります。

  • 複数のドキュメントを含むファイルからYAMLドキュメントを読み取る方法
  • そのYAMLドキュメントから必要なキーを選択する方法

Gregory Nisbettの回答を読んで、「DaemonSet」という種類のYAMLドキュメントが必要だと思いました。

Bashスクリプトでこれを実行したいので、システムに既にインストールされている可能性が高いツールのみを使用するようにします。あなたがJQを持っているのは、それがないとBashで多くのことを行うことが難しいためです。

YAMLライブラリの場合、Rubyを使用する傾向があります。

  • ほとんどのシステムにはRubyがあります
  • RubyのPsychライブラリはRuby 1.9以降にバンドルされています
  • PythonのPyYAMLライブラリは少し柔軟性がなく、私の経験ではRubyのものと比べて時々壊れています
  • PerlのYAMLライブラリは、デフォルトではインストールされないことがよくあります

yq を使用することをお勧めしましたが、YAMLドキュメントを抽出できるツールが必要なため、この場合はそれほど役に立ちません。

文書を抽出したら、もう一度Rubyを使用してファイルをJSONとして保存します。その後、jqを使用できます。

YAMLドキュメントの抽出

Rubyを使用してYAMLドキュメントを取得し、JSONとして保存するには:

url=...
curl -s $url | \
  Ruby -ryaml -rjson -e \
    "puts YAML.load_stream(ARGF.read)
      .select{|doc| doc['kind']=='DaemonSet'}[0].to_json" \
  | jq . > calico.json

詳細説明:

  • YAML.load_streamはYAMLドキュメントを読み取り、それらをすべて配列として返します
  • ARGF.readはSTDINを介して渡されたファイルから読み取ります
  • Rubyの選択により、種類キーに応じてYAMLドキュメントを簡単に選択できます
  • 次に、要素4を取得してJSONに変換します。

その応答をjq .人間が読めるようにフォーマットされていますが、そのステップは実際には必要ありません。 Ruby=でも同じことができますが、Rubyコードを最小限に抑えたいと思います。

必要なキーを選択します

必要なキーを選択するには、次のJQクエリを使用できます。

jq -r \
  '.spec.template.spec.containers[].env[] | select(.name=="CALICO_IPV4POOL_CIDR") | .value' \
  calico.json                                                          

詳細説明:

  • 最初の部分 spec.template.spec.containers[].env[]すべてのコンテナとその中のすべての環境に対して反復する
  • 次に、名前キーがCALICO_IPV4POOL_CIDRと等しいハッシュを選択し、値を返します
  • -rは、文字列を囲む引用符を削除します

すべてを一緒に入れて:

#!/usr/bin/env bash

url='https://docs.projectcalico.org/v3.3/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml'

curl -s $url | \
  Ruby -ryaml -rjson -e \
    "puts YAML.load_stream(ARGF.read)
      .select{|doc| doc['kind']=='DaemonSet'}[0].to_json" \
  | jq . > calico.json

jq -r \
  '.spec.template.spec.containers[].env[] | select(.name=="CALICO_IPV4POOL_CIDR") | .value' \
  calico.json

テスト:

▶ bash test.sh
192.168.0.0/16
0
Alex Harvey