как сгенерировать html-отчет для нескольких хостов с помощью ansible и jinja2
моя пьеса
- name: create HTML report
template:
src: report.j2
dest: /cktreport.html
delegate_to: localhost
run_once: true
report.j2
<!DOCTYPE html>
<html>
<body>
<table>
<thead>
<tr>
<th>HOSTNAME</th>
<th>PORT</th>
<th>CKTID</th>
</tr>
</thead>
<tbody>
{% for item in output.parsed %}
<tr>
{% if 'CID' in item.DESCRIP %}
<td>{{inventory_hostname}}</td>
<td>{{item.PORT}}</td>
<td>{{item.DESCRIP}}</td>
{%elif 'ckid' in item.DESCRIP %}
<td>{{inventory_hostname}}</td>
<td>{{item.PORT}}</td>
<td>{{item.DESCRIP}}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
'output.parsed' содержит информацию ниже
TASK [debug] *******************************************************************
ok: [host-1] => {
"msg": [
{
"DESCRIP": "CID: xxxx",
"PORT": "Gi0/0/0",
"PROTOCOL": "up",
"STATUS": "up"
},
{
"DESCRIP": "",
"PORT": "Gi0/0/1",
"PROTOCOL": "up",
"STATUS": "up"
},
{
"DESCRIP": "",
"PORT": "Gi0/0/2",
"PROTOCOL": "down",
"STATUS": "down"
},
{
"DESCRIP": "ckid: XXXX",
"PORT": "Gi0/0/3",
"PROTOCOL": "up",
"STATUS": "up"
}
]
}
ok: [host-2] => {
"msg": [
{
"DESCRIP": "CID: xxxx",
"PORT": "Gi0/0/1",
"PROTOCOL": "up",
"STATUS": "up"
},
{
"DESCRIP": "",
"PORT": "Gi0/0/6",
"PROTOCOL": "up",
"STATUS": "up"
},
{
"DESCRIP": "",
"PORT": "Gi0/0/7",
"PROTOCOL": "down",
"STATUS": "down"
},
{
"DESCRIP": "ckid: XXXX",
"PORT": "Gi0/0/8",
"PROTOCOL": "up",
"STATUS": "up"
}
]
}
У меня есть проблема - когда я запускаю playbook, cktreport.html создается только для хоста-1, у меня несколько хостов, как сгенерировать один / один cktreport.html таким образом, чтобы в нем была вся информация о хостах.
Я знаю, что мне нужно изменить шаблон jinja2, но не знаю, какую логику использовать.
1 ответ
Я считаю само собой разумеющимся, что твоя книга нацелена на волшебную группу
all
. Просто замените в шаблоне ниже правильную группу, если это не так.
Если вы делаете что-то более сложное (нацеливание на несколько групп, использование расширенного шаблона хоста, использование ограничений в командной строке ...), обратите внимание на специальные переменные, такие как
ansible_play_hosts
который будет более адаптирован.
В большинстве случаев это плохая практика - зацикливаться непосредственно на списках хостов за пределами естественного цикла хостов воспроизведения ... кроме случаев, когда есть веская причина, и эта. В вашем шаблоне вам нужно пройти по всем хостам, чтобы включить их в отчет, а затем зациклить на проанализированной информации, которую вы ранее собрали. Я считаю, что следующий шаблон должен соответствовать вашим требованиям (не проверено).
Примечания:
- поскольку
h
на самом деле содержитinventory_hostname
, Я использовал это прямо для краткости. Но вы можете заменить наhostvars[h].inventory_hostname
если хочешь. Результат будет абсолютно идентичным. - шаблон вашего примера был недействителен (закрытие
endfor
зависать без opennigfor
). Я исправил это ниже. - Я оставил твой
if
строфы, как они были, но у вас есть несколько вариантов СУШКИ здесь и проверить оба условия сразу (сmatch
или другие решения с регулярным выражением ...), чтобы впоследствии вывести тот же кусок html. Я позволю вам изучить это самостоятельно, если хотите.
<!DOCTYPE html>
<html>
<body>
<table>
<thead>
<tr>
<th>HOSTNAME</th>
<th>PORT</th>
<th>CKTID</th>
</tr>
</thead>
<tbody>
{% for h in groups['all'] %}
{% for item in hostvars[h].output.parsed %}
<tr>
{% if 'CID' in item.DESCRIP %}
<td>{{ h }}</td>
<td>{{ item.PORT }}</td>
<td>{{ item.DESCRIP }}</td>
{%elif 'ckid' in item.DESCRIP %}
<td>{{ h }}</td>
<td>{{ item.PORT }}</td>
<td>{{ item.DESCRIP }}</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
</tbody>
</table>
</body>
</html>