質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Ansible

Ansibleは、Python で書かれたサーバーの設定を管理するための 構成管理ツールです。

Cisco

シスコ(Cisco Systems,Inc.)は、アメリカ合衆国に本社を置く、世界最大のコンピュータネットワーク機器開発会社及び同社の製品

Q&A

解決済

1回答

2734閲覧

ansible)cisco機器から取得した情報をntc-templateを利用してcsv化した後、hostanameを先頭行に入れたい

sk11

総合スコア10

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Ansible

Ansibleは、Python で書かれたサーバーの設定を管理するための 構成管理ツールです。

Cisco

シスコ(Cisco Systems,Inc.)は、アメリカ合衆国に本社を置く、世界最大のコンピュータネットワーク機器開発会社及び同社の製品

0グッド

0クリップ

投稿2019/06/30 10:52

前提・実現したいこと

1.ansible + ntc-templateを利用
2.cisco機器から取得した情報をntc-templateとjinja2テンプレートを利用してcsvに変換。
3.csvファイルの先頭列に、hostnameを追加して保存する。

この1と2は出来たのですが、3つめの部分が出来ず実現させたい。

「JANOG42」の資料にある情報にアレンジを加えたい。
https://www.slideshare.net/akira6592/janog42-ansible-networkautomation
P.65~P.71参照

該当のソースコード

CSVにする部分までの情報
この例では、"show int status"を利用

yaml

1--- 2- name: SHOW INT STATUS 3 hosts: ios-l2sw 4 gather_facts: no 5 become: yes 6 become_method: enable 7 vars: 8 now_date: "{{ lookup('pipe','date +%Y%m%d%H%M')}}" 9 10 tasks: 11 - name: GATHER FACT 12 ios_facts: 13 14 - name: COLLECT OUTPUT OF SHOW INT STATUS 15 cli_command: 16 command: show int status 17 register: output 18 19 - name: OUTPUT CSV FILE 20 template: 21 src: "./jinja2_templates/template_show_int_status.txt" 22 dest: "./csv-files/sh_int_status/{{ ansible_net_hostname }}_{{ now_date }}_result_sh_int_status.csv" 23 vars: 24 parsed_result: "{{ output.stdout | parse_cli_textfsm('./templates/cisco_ios_show_interfaces_status.template') }}" 25

template_show_int_status.txt

j2

1"PORT","NAME","STATUS","VLAN","DUPLEX","SPEED","TYPE" 2{% for r in parsed_result %} 3"{{ r['PORT'] }}","{{ r['NAME'] }}","{{ r['STATUS'] }}","{{ r['VLAN'] }}","{{ r['DUPLEX'] }}","{{ r['SPEED'] }}","{{ r['TYPE'] }}" 4{% endfor %}

試したこと

全くの理解不足ですが、ansible側でios_factsの情報を取得しているので、j2テンプレートに入れ込んで見ました。
が、no attribute という事でエラーとなりました。

j2

1"HOSTNAME""PORT","NAME","STATUS","VLAN","DUPLEX","SPEED","TYPE" 2{% for r in parsed_result %} 3"{{ r['ansible_net_hostname'] }}","{{ r['PORT'] }}","{{ r['NAME'] }}","{{ r['STATUS'] }}","{{ r['VLAN'] }}","{{ r['DUPLEX'] }}","{{ r['SPEED'] }}","{{ 4r['TYPE'] }}" 5{% endfor %}

エラー

fatal: [HOSTXX]: FAILED! => { "changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'ansible_net_hostname'"

補足情報(FW/ツールのバージョンなど)

$ ansible --version ansible 2.7.9

下記参考にさせて頂いたサイトではpythonで実現させています。これをansible処理で完結させたいです。
http://kooshin.hateblo.jp/entry/2017/12/06/223407

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

urbainleverrier

2019/07/01 07:05

該当の'parsed_result'をdebugした結果はありますか
sk11

2019/07/01 11:09

確認ありがとうございます。該当のTASKのログは下記の通りです。(-vvvで実行した結果) 「ok=2」の部分は、該当のTASKの前に処理している2つの結果です。 ``` TASK [OUTPUT CSV FILE] *************************************************************************************************************************************** task path: /home/userxx/ntctemplate/sh_int_status.yml:19 <[HOSTXX]> ESTABLISH LOCAL CONNECTION FOR USER: userxx <[HOSTXX]> EXEC /bin/sh -c '( umask 77 && mkdir -p "` echo /home/userxx/.ansible/tmp/ansible-local-16551q5QN10/ansible-tmp-1561979043.66-38580980706491 `" && echo ansible-tmp-1561979043.66-38580980706491="` echo /home/userxx/.ansible/tmp/ansible-local-16551q5QN10/ansible-tmp-1561979043.66-38580980706491 `" ) && sleep 0' <[HOSTXX]> EXEC /bin/sh -c 'rm -f -r /home/userxx/.ansible/tmp/ansible-local-16551q5QN10/ansible-tmp-1561979043.66-38580980706491/ > /dev/null 2>&1 && sleep 0' fatal: [[HOSTXX]]: FAILED! => { "changed": false, "msg": "AnsibleUndefinedVariable: 'dict object' has no attribute 'ansible_net_hostname'" } PLAY RECAP *************************************************************************************************************************************************** [HOSTXX] : ok=2 changed=0 unreachable=0 failed=1 ```
urbainleverrier

2019/07/01 11:45

度々すみません、parsed_resultの各要素に、ansible_net_hostnameというkeyがないものと思いました。 ``` - name: debug parsed_result debug: msg: "{{ output.stdout | parse_cli_textfsm('./templates/cisco_ios_show_interfaces_status.template') }}" ``` のようにするとどうですか
sk11

2019/07/01 13:47

ありがとうございます。 ansible_net_hostname については前のTASKにある"ios_facts:"で取得してきた情報なんです。 伝え方が悪く申し訳け御座いません。 そもそも、理解が浅いので前のTASKで取得した情報をうまく利活用出来ないかなって発想でしたが、 一度生成されたCSVファイルに列を追加したいのが意図になるので、この方法にこだわっている訳では なく、それ以外の方法が見いだせない状況です。 参考にした下記サイトを見ると http://kooshin.hateblo.jp/entry/2017/12/06/223407 1.Pythonライブラリのnetmikoを利用して情報を収集 2.textfsm+ntc-templatesを利用して必要な情報をCSVに保存 3.下記の部分で列を先頭に列を追加    # 各行の先頭にホスト名を付与    inventory = [[host['hostname']] + row for row in result]   ⇒ この部分をansibleの処理の中で実現させたい意図になります。 もう一度、templateモジュールを回せば良いのであれば、実際にどんな設定になるのか? それとも、違う手法があるのか等、ご教授頂けると幸いです。 下記の様な情報も近そうな気がしますが、まだ理解しきれていなく。。 https://codeday.me/jp/qa/20190329/492467.html https://qiita.com/yteraoka/items/7119d4e1e2f8faddfb64 よろしくお願いいたします。
urbainleverrier

2019/07/02 03:58

すみません、見当違いでした また違うかもしれませんが、 csvのデータとなるlistが与えられていれば、 1. list | join(',')でカンマ区切りの文字列をset_factを使って変数にする(i.e. data: '{{ list | join(',') }}') 2. さらにhostnameを与えて変数にする(i.e. row: '{{ host['hostname'] }}, {{ data }}') 3. templateやlineinefileモジュール?を使って対象データ{{ row }}を追加する これは解決につながりますか?
sk11

2019/07/02 22:01

毎度ありがとう御座います。 所用で直ぐに試せないのですが、試し次第御連絡致します。
sk11

2019/07/04 12:35

tktktさん 色々ありがとうございました。 会話しているなかで調べていて、何とか解決出来ました。 解決欄に書いておきます。
guest

回答1

0

自己解決

解決方法

1.templateモジュール利用時に、with_itemsで改めて"{{ ansible_net_hostname }}"を定義。
2.jinja2のテンプレートにて、"{{ item }}"としてCSVリストの頭に定義

苦労しましたが、解決方法はかなりシンプル&単純な対応でした。。

"{{ ansible_net_hostname }}"については、ios_facts:にて取得しているものを利用していますが、"{{ inventory_hostname }}"として、一つ目のtaskは無くしても良いかもしれません。

hostnameを入れる場所は、templateの設定を移動すればOKですね。

これで楽できそうです。

sh_int_status.yml

yml

1--- 2- name: SHOW INT STATUS 3 hosts: ios-l2sw 4 gather_facts: no 5 become: yes 6 become_method: enable 7 vars: 8 now_date: "{{ lookup('pipe','date +%Y%m%d%H%M')}}" 9 10 tasks: 11 - name: GATHER FACT 12 ios_facts: 13 14 - name: COLLECT OUTPUT OF SHOW INT STATUS 15 cli_command: 16 command: show int status 17 register: output 18 19 - name: OUTPUT CSV FILE 20 template: 21 src: "./jinja2_templates/template_show_int_status.txt" 22 dest: "./csv-files/sh_int_status/{{ ansible_net_hostname }}_{{ now_date }}_result_sh_int_status.csv" 23 vars: 24 parsed_result: "{{ output.stdout | parse_cli_textfsm('./templates/cisco_ios_show_interfaces_status.template') }}" 25 with_items: 26 - "{{ ansible_net_hostname }}"

template_show_int_status.txt

j2

1"HOSTNAME","PORT","NAME","STATUS","VLAN","DUPLEX","SPEED","TYPE" 2{% for r in parsed_result %} 3"{{ item }}","{{ r['PORT'] }}","{{ r['NAME'] }}","{{ r['STATUS'] }}","{{ r['VLAN'] }}","{{ r['DUPLEX'] }}","{{ r['SPEED'] }}","{{ r['TYPE'] } 4}" 5{% endfor %} 6

投稿2019/07/04 12:48

sk11

総合スコア10

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問