ansible/jmespath/jqを使用してエスケープされたjson文字列を解析する方法は?

ansible/jmespath/jqを使用してエスケープされたjson文字列を解析する方法は?

私はBluecatのAnsibleモジュールを使用してサブネットに関するいくつかの情報を取得するための認証API呼び出しを作成しています。応答は次のとおりです。

"result": {
        "changed": false,
        "failed": false,
        "json": "b'{\"id\":12345,\"name\":\"SUBNET NAME\",\"properties\":\"CIDR=10.2.2.0/24|allowDuplicateHost=enable|pingBeforeAssign=disable|inheritAllowDuplicateHost=true|inheritPingBeforeAssign=true|gateway=10.2.2.1|inheritDNSRestrictions=true|inheritDefaultDomains=true|inheritDefaultView=true|\",\"type\":\"IP4Network\"}\\n'",
        "msg": "",
        "status": 200
}

ご覧のとおり、便利なデータはすべてフィールドにありますが、jsonエスケープされた引用符と改行文字を含む不快な文字列リテラルです。走れば

- debug:
      msg: "{{ result | json_query('json.name') }}"

Ansibleはmsg代わりにフィールドを提供します!フィールド全体jsonを取得できますが、内容はまったく取得できません。少し修正して、b先頭の余分なバックスラッシュ、内部一重引用符、末尾の改行文字を切り取るとjq .json | fromjson正しく解析されます。しかし、私はそれが単にバイトエンコーディングを意味し、解析を中断するべきではないと確信していますが、b''そうです。最後に二重バックスラッシュはどうなりますか?

sed脱出したすべてのキャラクターを殺すために黒魔法を使用する以外に他のオプションはありますか? Web APIはなぜそのような文字列を返すのですか?

答え1

中かっこ以外の内容を削除すると、{}Ansible は辞書を解析します。

  subnet: "{{ result.json[2:-3] }}"

与えられた

  subnet:
    id: 12345
    name: SUBNET NAME
    properties: CIDR=10.2.2.0/24|allowDuplicateHost=enable|pingBeforeAssign=disable|inheritAllowDuplicateHost=true|inheritPingBeforeAssign=true|gateway=10.2.2.1|inheritDNSRestrictions=true|inheritDefaultDomains=true|inheritDefaultView=true|
    type: IP4Network

オプションで、より強力なストライピングを使用します。たとえば、次の式は同じ結果を提供します。

  subnet: "{{ result.json|regex_replace(_regex, _replace) }}"
  _regex: '^.*?\{(.*)\}.*$'
  _replace: '{\1}'

属性を解析する場合特徴同様に、次の式も

  subnet_prop: "{{ subnet|combine({'properties': dict(_prop)}) }}"
  _prop: "{{ subnet.properties.split('|')|select|map('split', '=')|list }}"

与えられた

  subnet_prop:
    id: 12345
    name: SUBNET NAME
    properties:
      CIDR: 10.2.2.0/24
      allowDuplicateHost: enable
      gateway: 10.2.2.1
      inheritAllowDuplicateHost: 'true'
      inheritDNSRestrictions: 'true'
      inheritDefaultDomains: 'true'
      inheritDefaultView: 'true'
      inheritPingBeforeAssign: 'true'
      pingBeforeAssign: disable
    type: IP4Network

ブール値は上記の辞書で文字列として表示されます。これが問題の場合は交換してください分けるフィルター正規表現_交換そしてfrom_yaml。フィルターもそのような場合分けるない

  _prop: "{{ subnet.properties.split('|')|
             select|
             map('regex_replace', '^(.*)=(.*)$', '[\\1, \\2]')|
             map('from_yaml')|list }}"

与えられた

  subnet_prop:
    id: 12345
    name: SUBNET NAME
    properties:
      CIDR: 10.2.2.0/24
      allowDuplicateHost: enable
      gateway: 10.2.2.1
      inheritAllowDuplicateHost: true
      inheritDNSRestrictions: true
      inheritDefaultDomains: true
      inheritDefaultView: true
      inheritPingBeforeAssign: true
      pingBeforeAssign: disable
    type: IP4Network

関連情報