## -*- coding: utf-8 -*-
<%! from jsonxs import jsonxs %>
<%! import datetime %>
<%! import socket %>
<%! import getpass %>
<%! from ansiblecmdb.util import to_bool %>
<%! from mako.template import Template %>
##
## Column definitions
##
<%def name="var_cols(cols_visible=None, cols_exclude=None)">
<%
# These are the baked in columns. The user can also extend these columns
# through --cust-cols, in which case those columns are appended to this list
# (in the calling template file).
cols = [
{"title": "Name", "id": "name", "func": col_name, "sType": "string", "visible": True},
{"title": "Groups", "id": "groups", "func": col_groups, "sType": "string", "visible": False},
{"title": "Cust", "id": "cust", "func": col_cust, "sType": "string", "visible": False},
{"title": "DTAP", "id": "dtap", "func": col_dtap, "sType": "string", "visible": False},
{"title": "Comment", "id": "comment", "func": col_comment, "sType": "string", "visible": False},
{"title": "Ext ID", "id": "ext_id", "func": col_ext_id, "sType": "string", "visible": False},
{"title": "FQDN", "id": "fqdn", "func": col_fqdn, "sType": "string", "visible": True},
{"title": "Main IP", "id": "main_ip", "func": col_main_ip, "sType": "string", "visible": True},
{"title": "All IPv4", "id": "all_ipv4", "func": col_all_ip4, "sType": "string", "visible": False},
{"title": "All IPv6", "id": "all_ipv6", "func": col_all_ip6, "sType": "string", "visible": False},
{"title": "OS", "id": "os", "func": col_os, "sType": "string", "visible": True},
{"title": "Kernel", "id": "kernel", "func": col_kernel, "sType": "string", "visible": False},
{"title": "Arch", "id": "arch", "func": col_arch, "sType": "string", "visible": False},
{"title": "Virt", "id": "virt", "func": col_virt, "sType": "string", "visible": True},
{"title": "CPU type", "id": "cpu_type", "func": col_cpu_type, "sType": "string", "visible": False},
{"title": "vCPUs", "id": "vcpus", "func": col_vcpus, "sType": "num", "visible": True},
{"title": "RAM [GiB]", "id": "ram", "func": col_ram, "sType": "num", "visible": True},
{"title": "Mem Usage", "id": "mem_usage", "func": col_mem_usage, "sType": "string", "visible": False},
{"title": "Swap Usage", "id": "swap_usage", "func": col_swap_usage, "sType": "string", "visible": False},
{"title": "Disk usage", "id": "disk_usage", "func": col_disk_usage, "sType": "string", "visible": False},
{"title": "PhysDisk size", "id": "physdisk_size", "func": col_physdisk_sizes, "sType": "string", "visible": False},
{"title": "Nr of Ifaces", "id": "nr_of_ifaces", "func": col_nr_of_ifaces, "sType": "num", "visible": False},
{"title": "Timestamp", "id": "timestamp", "func": col_gathered, "sType": "string", "visible": False},
{"title": "Product Name", "id": "prodname", "func": col_prodname, "sType": "string", "visible": False},
{"title": "Product Serial","id": "prodserial", "func": col_prodserial, "sType": "string", "visible": False},
]
# Enable columns specified with '--columns'
if cols_visible is not None:
for col in cols:
if col["id"] in cols_visible:
col["visible"] = True
else:
col["visible"] = False
# Remove columns that should be excluded
if cols_exclude is not None:
cols = filter(lambda col: col["id"] not in cols_exclude, cols)
return cols
%>
%def>
##
## Helper functions for dumping python datastructures
##
<%def name="r_list(l, sort=False)">
<%
if sort is True:
try:
l = sorted(l)
except TypeError:
# Can't sort contents of l
pass
%>
% for i in l:
% if type(i) == list:
${r_list(i, sort=sort)}
% elif type(i) == dict:
${r_dict(i, sort=sort)}
% else:
${i}
% endif
% endfor
%def>
<%def name="r_dict(d, sort=False)">
<%
keys = d.keys()
if sort is True:
keys = sorted(keys)
%>
% for k in keys:
<% v = d[k] %>
% if type(k) == "str":
${k.replace('ansible_', '')}
% else:
${k}
% endif
|
% if type(v) == list:
${r_list(v, sort=sort)}
% elif type(v) == dict:
${r_dict(v, sort=sort)}
% else:
${v}
% endif
|
% endfor
%def>
##
## HTML fragments
##
<%def name="html_header(title, local_js, res_url)">
${title}
% if local_js is False:
% else:
% endif
%def>
<%def name="html_header_bar(title)">
${title}
Back to top
Clear settings
Generated on ${datetime.datetime.now().strftime('%c')} by ${getpass.getuser()} @ ${socket.getfqdn()}
%def>
<%def name="html_footer_bar(version)">
%def>
<%def name="html_footer()">
%def>
<%def name="html_col_toggles(cols)">
%def>
<%def name="html_host_overview(cols, hosts, skip_empty=False, **kwargs)">
Host overview
% for col in cols:
${col['title']} |
% endfor
% for hostname, host in hosts.items():
<% log.debug(u"Rendering host overview for {0}".format(hostname)) %>
% if skip_empty is False or 'ansible_facts' in host:
\
% for col in cols:
% if "func" in col:
${col["func"](host, **kwargs)} | \
% elif "jsonxs" in col:
${col__cust_jsonxs(host, col=col, **kwargs)} | \
% elif "tpl" in col:
${col__cust_tpl(host, col=col, **kwargs)} | \
% endif
% endfor
% endif
% endfor
%def>
<%def name="html_host_details(hosts, collapsed=False, skip_empty=False)">
% for hostname, host in hosts.items():
<%
log.debug(u"Rendering host details for {0}".format(hostname))
%>
<% html_host_detail(host, collapsed=collapsed, skip_empty=skip_empty) %>
% endfor
%def>
<%def name="html_host_detail(host, collapsed=False, skip_empty=False)">
<%
collapsed_class = "uncollapsed"
collapse_toggle_text = "Close all"
if collapsed is True:
collapsed_class = "collapsed"
collapse_toggle_text = "Open all"
%>
% if skip_empty is False or 'ansible_facts' in host:
${host['name']}
${collapse_toggle_text}
% if 'ansible_facts' not in host:
No host information collected
% if 'msg' in host:
${host['msg']}
% endif
<% host_groups(host, collapsed_class) %>
<% host_custvars(host, collapsed_class) %>
% else:
<% host_general(host, collapsed_class) %>
<% host_groups(host, collapsed_class) %>
<% host_custvars(host, collapsed_class) %>
<% host_localfacts(host, collapsed_class) %>
<% host_factorfacts(host, collapsed_class) %>
<% host_customfacts(host, collapsed_class) %>
<% host_hardware(host, collapsed_class) %>
<% host_os(host, collapsed_class) %>
<% host_network(host, collapsed_class) %>
<% host_storage(host, collapsed_class) %>
% endif
% endif
%def>
##
## Javascript fragments
##
<%def name="js_init_host_overview(cols)">
function getQueryParams(qs) {
qs = qs.split('+').join(' ');
var params = {},
tokens,
re = /[?&]?([^=]+)=([^&]*)/g;
while (tokens = re.exec(qs)) {
params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
}
return params;
}
// Get persisted column visibility from localStorage.
var columnVisibility = localStorage.getItem("columnVisibility");
if (columnVisibility == null) {
columnVisibility = {
% for col in cols:
"${col["id"]}": ${str(col["visible"]).lower()},
% endfor
};
localStorage.setItem("columnVisibility", JSON.stringify(columnVisibility));
} else {
columnVisibility = JSON.parse(columnVisibility);
}
// Initialize the DataTables jQuery plugin on the host overview table
var table = $('#host_overview_tbl').DataTable({
paging: false,
columnDefs: [
% for col in cols:
{
"targets": [${loop.index}],
"visible": ${str(col['visible']).lower()},
"sType": "${col['sType']}"
},
% endfor
],
"fnInitComplete": function() {
// Focus the input field
$("#host_overview_tbl_filter input").focus();
// Set the search box value to the query string 'search' part
var qp = getQueryParams(document.location.search);
if ("search" in qp) {
$("#host_overview_tbl_filter input").val(qp.search);
this.fnFilter(qp.search);
}
}
});
// Display or hide columns based on localStorage preferences.
for (var columnId in columnVisibility) {
var columnButton = $("a[data-column-id='" + columnId +"']");
var columnNr = columnButton.attr('data-column');
var column = table.column(columnNr);
column.visible(columnVisibility[columnId]);
var newClass = ['col-invisible','col-visible'][Number(column.visible())];
columnButton.get(0).className = 'col-toggle ' + newClass;
}
// Show a direct link to the search term
table.on( 'search.dt', function () {
$('#filter_link').remove();
if (table.search() == "") {
} else {
$('#host_overview_tbl_filter label').after(' ');
}
} );
// Show and hide columns on button clicks
$('a.col-toggle').on('click', function(e) {
e.preventDefault();
var columnId = $(this).attr('data-column-id')
var column = table.column( $(this).attr('data-column') );
column.visible( ! column.visible() );
var newClass = ['col-invisible','col-visible'][Number(column.visible())];
e.target.className = 'col-toggle ' + newClass;
// Storage column visibility in localStorage.
columnVisibility[columnId] = column.visible();
localStorage.setItem("columnVisibility", JSON.stringify(columnVisibility));
});
// Open the Detailed host information when jumping to a host.
$('#host_overview td a').on('click', function(e) {
var hostId=$(this).attr('href').substr(1);
var hostElem = $("h3[data-host-name='"+hostId+"']");
hostElem.addClass('uncollapsed');
hostElem.removeClass('collapsed');
hostElem.next().removeClass('collapsed');
});
%def>
<%def name="js_ev_collapse()">
// Open the detailed host information when clicking on the hosts header
$('.toggle-collapse').on('click', function(e) {
$(this).toggleClass('collapsed');
$(this).toggleClass('uncollapsed');
$(this).next().toggleClass('collapsed');
});
// Toggle opening and closing all information for a host.
$('a.toggle-all').on('click', function(e) {
e.preventDefault();
if ($(this).text() == "Open all") {
$(this).siblings('.collapsed').each(function(item) {
$(this).addClass('uncollapsed');
$(this).removeClass('collapsed');
$(this).next().toggleClass('collapsed');
});
$(this).text("Close all");
} else {
$(this).text("Open all");
$(this).siblings('.uncollapsed').each(function(item) {
$(this).addClass('collapsed');
$(this).removeClass('uncollapsed');
$(this).next().toggleClass('collapsed');
});
}
});
%def>
##
## Column functions
##
## Each column function takes variable kwargs. These are not properly unpacked
## in the function scope in Mako for some reason, so if we need to use them, we
## need to do a `kwargs.get()`. I don't like Mako much.
<%def name="col__cust_jsonxs(host, col, **kwargs)">
## Special column function for custom columns that does a jsonxs lookup
${jsonxs(host, col["jsonxs"], default='')}
%def>
<%def name="col__cust_tpl(host, col, **kwargs)">
## Special column function for custom columns that renders a string template
${Template(col["tpl"]).render(host=host, jsonxs=jsonxs)}
%def>
<%def name="col_name(host, **kwargs)">
<%
link_type = kwargs.get("link_type")
elem_class = ""
if "ansible_facts" not in host:
elem_class = "error"
%>
% if link_type == "anchor":
${jsonxs(host, "name")}
% elif link_type == "external":
${jsonxs(host, 'name')}
% else:
${jsonxs(host, "name")}
% endif
%def>
<%def name="col_dtap(host, **kwargs)">
${jsonxs(host, 'hostvars.dtap', default='')}
%def>
<%def name="col_groups(host, **kwargs)">
${'
'.join(jsonxs(host, 'groups', default=''))}
%def>
<%def name="col_cust(host, **kwargs)">
${jsonxs(host, 'hostvars.cust', default='')}
%def>
<%def name="col_fqdn(host, **kwargs)">
${jsonxs(host, 'ansible_facts.ansible_fqdn', default='')}
%def>
<%def name="col_main_ip(host, **kwargs)">
<%
default_ipv4 = ''
if jsonxs(host, 'ansible_facts.ansible_os_family', default='') == 'Windows':
ipv4_addresses = [ip for ip in jsonxs(host, 'ansible_facts.ansible_ip_addresses', default=[]) if ':' not in ip]
if ipv4_addresses:
default_ipv4 = ipv4_addresses[0]
else:
default_ipv4 = jsonxs(host, 'ansible_facts.ansible_default_ipv4.address', default='')
%>
${default_ipv4}
%def>
<%def name="col_all_ip4(host, **kwargs)">
<%
if jsonxs(host, 'ansible_facts.ansible_os_family', default='') == 'Windows':
ipv4_addresses = [ip for ip in jsonxs(host, 'ansible_facts.ansible_ip_addresses', default=[]) if ':' not in ip]
else:
ipv4_addresses = jsonxs(host, 'ansible_facts.ansible_all_ipv4_addresses', default=[])
%>
${'
'.join(ipv4_addresses)}
%def>
<%def name="col_all_ip6(host, **kwargs)">
${'
'.join(jsonxs(host, 'ansible_facts.ansible_all_ipv6_addresses', default=[]))}
%def>
<%def name="col_os(host, **kwargs)">
% if jsonxs(host, 'ansible_facts.ansible_distribution', default='') in ["OpenBSD"]:
${jsonxs(host, 'ansible_facts.ansible_distribution', default='')} ${jsonxs(host, 'ansible_facts.ansible_distribution_release', default='')}
% else:
${jsonxs(host, 'ansible_facts.ansible_distribution', default='')} ${jsonxs(host, 'ansible_facts.ansible_distribution_version', default='')}
% endif
%def>
<%def name="col_kernel(host, **kwargs)">
${jsonxs(host, 'ansible_facts.ansible_kernel', default='')}
%def>
<%def name="col_arch(host, **kwargs)">
${jsonxs(host, 'ansible_facts.ansible_architecture', default='')} / ${jsonxs(host, 'ansible_facts.ansible_userspace_architecture', default='')}
%def>
<%def name="col_virt(host, **kwargs)">
${jsonxs(host, 'ansible_facts.ansible_virtualization_type', default='?')} / ${jsonxs(host, 'ansible_facts.ansible_virtualization_role', default='?')}
%def>
<%def name="col_cpu_type(host, **kwargs)">
<% cpu_type = jsonxs(host, 'ansible_facts.ansible_processor', default=0)%>
% if isinstance(cpu_type, list) and len(cpu_type) > 0:
${ cpu_type[-1] }
% endif
%def>
<%def name="col_vcpus(host, **kwargs)">
% if jsonxs(host, 'ansible_facts.ansible_distribution', default='') in ["OpenBSD"]:
0
% else:
${jsonxs(host, 'ansible_facts.ansible_processor_vcpus', default=jsonxs(host, 'ansible_facts.ansible_processor_cores', default=0))}
% endif
%def>
<%def name="col_ram(host, **kwargs)">
${'%0.1f' % ((int(jsonxs(host, 'ansible_facts.ansible_memtotal_mb', default=0)) / 1024.0))}
%def>
<%def name="col_mem_usage(host, **kwargs)">
% try:
<%
i = jsonxs(host, 'ansible_facts.ansible_memory_mb', default=0)
sort_used = '%f' % (float(jsonxs(i, "nocache.used", default=0)) / jsonxs(i, "real.total", default=0))
used = float(i["nocache"]["used"]) / i["real"]["total"] * 100
detail_used = round(jsonxs(i, "nocache.used", default=0) / 1024.0, 1)
detail_total = round(jsonxs(i, "real.total", default=0) / 1024.0, 1)
%>
## hidden sort helper
${sort_used}
(${detail_used} / ${detail_total} GiB)
% except:
n/a
% endtry
%def>
<%def name="col_swap_usage(host, **kwargs)">
% try:
<%
i = jsonxs(host, 'ansible_facts.ansible_memory_mb', default=0)
sort_used = '%f' % (float(jsonxs(i, "swap.used", default=0)) / jsonxs(i, "swap.total", default=0))
used = float(jsonxs(i, "swap.used", default=0)) / jsonxs(i, "swap.total", default=0) * 100
detail_used = round((jsonxs(i, "swap.used", default=0)) / 1024.0, 1)
detail_total = round(jsonxs(i, "swap.total", default=0) / 1024.0, 1)
%>
## hidden sort helper
${sort_used}
(${detail_used} / ${detail_total} GiB)
% except:
n/a
% endtry
%def>
<%def name="col_disk_usage(host, **kwargs)">
% for i in jsonxs(host, 'ansible_facts.ansible_mounts', default=[]):
% try:
<%
try:
sort_used = '%f' % (float((i["size_total"] - i["size_available"])) / i["size_total"])
used = float((i["size_total"] - i["size_available"])) / i["size_total"] * 100
detail_used = round((i['size_total'] - i['size_available']) / 1073741824.0, 1)
detail_total = round(i['size_total'] / 1073741824.0, 1)
except ZeroDivisionError:
sort_used = '0'
used = 0
detail_used = 0
detail_total = 0
%>
## hidden sort helper
${sort_used}
${i['mount']} (${detail_used} / ${detail_total} GiB)
% except:
n/a
<%
break ## Stop listing disks, since there was an error.
%>
% endtry
% endfor
%def>
<%def name="col_physdisk_sizes(host, **kwargs)">
% try:
% for physdisk_name, physdisk_info in jsonxs(host, 'ansible_facts.ansible_devices', default={}).items():
${physdisk_name}: ${jsonxs(physdisk_info, 'size', default='')}
% endfor
% except AttributeError:
% endtry
%def>
<%def name="col_nr_of_ifaces(host, **kwargs)">
${len(jsonxs(host, 'ansible_facts.ansible_interfaces', default=[]))}
%def>
<%def name="col_comment(host, **kwargs)">
${jsonxs(host, 'hostvars.comment', default='')}
%def>
<%def name="col_ext_id(host, **kwargs)">
${jsonxs(host, 'hostvars.ext_id', default='')}
%def>
<%def name="col_gathered(host, **kwargs)">
${jsonxs(host, 'ansible_facts.ansible_date_time.iso8601', default='')}
%def>
<%def name="col_prodname(host, **kwargs)">
${jsonxs(host, 'ansible_facts.ansible_product_name', default='')}
%def>
<%def name="col_prodserial(host, **kwargs)">
${jsonxs(host, 'ansible_facts.ansible_product_serial', default='')}
%def>
##
## Detailed host information blocks
##
<%def name="host_general(host, collapsed_class)">
General
Node name | ${jsonxs(host, 'ansible_facts.ansible_nodename', default='')} |
Form factor | ${jsonxs(host, 'ansible_facts.ansible_form_factor', default='')} |
Virtualization role | ${jsonxs(host, 'ansible_facts.ansible_virtualization_role', default='')} |
Virtualization type | ${jsonxs(host, 'ansible_facts.ansible_virtualization_type', default='')} |
%def>
<%def name="host_groups(host, collapsed_class)">
% if len(host.get('groups', [])) != 0:
Groups
% for group in sorted(host.get('groups', [])):
- ${group}
% endfor
% endif
%def>
<%def name="host_custvars(host, collapsed_class)">
% if len(host['hostvars']) != 0:
Custom variables
Careful: these variables may be overridden in various places by Ansible
% for var_name in sorted(host.get('hostvars', {}).keys()):
<%
var_value = host['hostvars'][var_name]
%>
${var_name} |
% if type(var_value) == dict:
${r_dict(var_value)}
% elif type(var_value) == list:
${r_list(var_value)}
% else:
${var_value}
% endif
|
% endfor
% endif
%def>
<%def name="host_localfacts(host, collapsed_class)">
% if len(jsonxs(host, 'ansible_facts.ansible_local', default={}).items()) != 0:
Host local facts
${r_dict(jsonxs(host, 'ansible_facts.ansible_local', default={}), sort=True)}
% endif
%def>
<%def name="host_factorfacts(host, collapsed_class)">
<%
facter_facts = {}
for key, value in jsonxs(host, 'ansible_facts', default={}).items():
if key.startswith('facter_'):
facter_facts[key] = value
%>
% if len(facter_facts) != 0:
Facter facts
${r_dict(facter_facts, sort=True)}
% endif
%def>
<%def name="host_customfacts(host, collapsed_class)">
% if len(host.get('custom_facts', {}).items()) != 0:
Custom facts
${r_dict(host.get('custom_facts', {}), sort=True)}
% endif
%def>
<%def name="host_hardware(host, collapsed_class)">
Hardware
Vendor | ${jsonxs(host, 'ansible_facts.ansible_system_vendor', default='')} |
Product name | ${jsonxs(host, 'ansible_facts.ansible_product_name', default='')} |
Product serial | ${jsonxs(host, 'ansible_facts.ansible_product_serial', default='')} |
Architecture | ${jsonxs(host, 'ansible_facts.ansible_architecture', default='')} |
Form factor | ${jsonxs(host, 'ansible_facts.ansible_form_factor', default='')} |
Virtualization role | ${jsonxs(host, 'ansible_facts.ansible_virtualization_role', default='')} |
Virtualization type | ${jsonxs(host, 'ansible_facts.ansible_virtualization_type', default='')} |
Machine | ${jsonxs(host, 'ansible_facts.ansible_machine', default='')} |
Processor type | ${jsonxs(host, 'ansible_facts.ansible_processor[-1]', default='')} |
Processor count | ${jsonxs(host, 'ansible_facts.ansible_processor_count', default='')} |
Processor cores | ${jsonxs(host, 'ansible_facts.ansible_processor_cores', default='')} |
Processor threads per core | ${jsonxs(host, 'ansible_facts.ansible_processor_threads_per_core', default='')} |
Processor virtual CPUs | ${jsonxs(host, 'ansible_facts.ansible_processor_vcpus', default='')} |
Mem total mb | ${jsonxs(host, 'ansible_facts.ansible_memtotal_mb', default='')} |
Mem free mb | ${jsonxs(host, 'ansible_facts.ansible_memfree_mb', default='')} |
Swap total mb | ${jsonxs(host, 'ansible_facts.ansible_swaptotal_mb', default='')} |
Swap free mb | ${jsonxs(host, 'ansible_facts.ansible_swapfree_mb', default='')} |
%def>
<%def name="host_os(host, collapsed_class)">
Operating System
System | ${jsonxs(host, 'ansible_facts.ansible_system', default='')} |
OS Family | ${jsonxs(host, 'ansible_facts.ansible_os_family', default='')} |
Distribution | ${jsonxs(host, 'ansible_facts.ansible_distribution', default='')} |
Distribution version | ${jsonxs(host, 'ansible_facts.ansible_distribution_version', default='')} |
Distribution release | ${jsonxs(host, 'ansible_facts.ansible_distribution_release', default='')} |
Kernel | ${jsonxs(host, 'ansible_facts.ansible_kernel', default='')} |
Userspace bits | ${jsonxs(host, 'ansible_facts.ansible_userspace_bits', default='')} |
Userspace_architecture | ${jsonxs(host, 'ansible_facts.ansible_userspace_architecture', default='')} |
Date time | ${jsonxs(host, 'ansible_facts.ansible_date_time.iso8601', default='')} |
Locale / Encoding | ${jsonxs(host, 'ansible_facts.ansible_env.LC_ALL', default='Unknown')} |
% if type(jsonxs(host, 'ansible_facts.ansible_selinux', default=false)) == bool:
SELinux | ${jsonxs(host, 'ansible_facts.ansible_selinux', default='Unknown')} |
% else:
SELinux | ${r_dict(jsonxs(host, 'ansible_facts.ansible_selinux', default={}), sort=True)} |
% endif
Package manager | ${jsonxs(host, 'ansible_facts.ansible_pkg_mgr', default='')} |
%def>
<%def name="host_network(host, collapsed_class)">
Network
Hostname | ${jsonxs(host, 'ansible_facts.ansible_hostname', default='')} |
Domain | ${jsonxs(host, 'ansible_facts.ansible_domain', default='')} |
FQDN | ${jsonxs(host, 'ansible_facts.ansible_fqdn', default='')} |
All IPv4 | ${' '.join(jsonxs(host, 'ansible_facts.ansible_all_ipv4_addresses', default=[]))} |
All IPv6 | ${' '.join(jsonxs(host, 'ansible_facts.ansible_all_ipv6_addresses', default=[]))} |
% if jsonxs(host, 'ansible_facts.ansible_os_family', default='') != "Windows":
IPv4 Networks |
dev |
address |
network |
netmask |
% for iface_name in sorted(jsonxs(host, 'ansible_facts.ansible_interfaces', default=[])):
<% iface = jsonxs(host, 'ansible_facts.ansible_' + iface_name, default={}) %>
% for net in [iface.get('ipv4', {})] + iface.get('ipv4_secondaries', []):
% if 'address' in net:
${iface_name} |
${net['address']} |
${net['network']} |
% if 'netmask' in net:
${net['netmask']} |
% else:
|
% endif
% endif
% endfor
% endfor
|
% endif
<% ifaces = jsonxs(host, 'ansible_facts.ansible_interfaces', default=[]) %>
% if len(ifaces) > 0:
Interface details |
% if isinstance(ifaces[0], str):
## Interfaces are strings and the interface details are found in
## ansible_facts.ansible_{interfacename}
% for iface in sorted(ifaces):
${iface} |
% try:
${r_dict(jsonxs(host, 'ansible_facts.ansible_%s' % (iface)))}
% except KeyError:
No information available
% endtry
|
% endfor
% elif isinstance(ifaces[0], dict):
## Interfaces are dicts, with the interface details already in it.
% for iface in ifaces:
${r_dict(iface)}
% endfor
% endif
|
% endif
%def>
<%def name="host_storage(host, collapsed_class)">
Storage
Devices |
% if type(jsonxs(host, 'ansible_facts.ansible_devices', default=[])) == list:
${r_list(jsonxs(host, 'ansible_facts.ansible_devices', default=[]))}
% else:
${r_dict(jsonxs(host, 'ansible_facts.ansible_devices', default={}))}
% endif
|
Mounts |
${r_list(host['ansible_facts'].get('ansible_mounts', []))}
|
%def>