mirror of
https://github.com/webmin/webmin.git
synced 2026-06-05 04:40:24 +01:00
194 lines
5.2 KiB
Perl
Executable File
194 lines
5.2 KiB
Perl
Executable File
#!/usr/local/bin/perl
|
|
# Display Kea runtime lease, pool, statistics, and log information.
|
|
|
|
use strict;
|
|
use warnings;
|
|
require './kea-dhcp-lib.pl'; ## no critic
|
|
&ReadParse();
|
|
our (%in, %text);
|
|
&error_setup($text{'eacl_aviol'});
|
|
&kea_assert_acl('runtime');
|
|
|
|
&ui_print_header(undef, $text{'runtime_title'}, "", undef, 1, 1);
|
|
|
|
# Keep runtime views grouped in one page so the module index stays focused on
|
|
# configuration, while admins still get the operational data old dhcpd exposed.
|
|
my @tabs = (
|
|
[ 'active', $text{'tab_leases_active'} ],
|
|
[ 'pools', $text{'tab_leases_pools'} ],
|
|
[ 'stats', $text{'tab_leases_stats'} ],
|
|
[ 'logs', $text{'tab_leases_logs'} ],
|
|
);
|
|
my %valid = map { $_->[0] => 1 } @tabs;
|
|
my $mode = $in{'mode'} && $valid{$in{'mode'}} ? $in{'mode'} : 'active';
|
|
print &ui_tabs_start(\@tabs, "mode", $mode, 1);
|
|
|
|
print &ui_tabs_start_tab("mode", "active");
|
|
my ($dhcp4_lease_file) = &kea_lease_file(4);
|
|
my ($dhcp6_lease_file) = &kea_lease_file(6);
|
|
print &ui_div(&text('leases_desc',
|
|
&sane_file_cell($dhcp4_lease_file),
|
|
&sane_file_cell($dhcp6_lease_file)));
|
|
&print_active_leases(4);
|
|
&print_active_leases(6);
|
|
print &ui_tabs_end_tab("mode", "active");
|
|
|
|
print &ui_tabs_start_tab("mode", "pools");
|
|
print &ui_div($text{'leases_pools_desc'});
|
|
&print_pool_usage(4);
|
|
&print_pool_usage(6);
|
|
print &ui_tabs_end_tab("mode", "pools");
|
|
|
|
print &ui_tabs_start_tab("mode", "stats");
|
|
print &ui_div($text{'leases_stats_desc'});
|
|
&print_lease_statistics();
|
|
print &ui_tabs_end_tab("mode", "stats");
|
|
|
|
print &ui_tabs_start_tab("mode", "logs");
|
|
print &ui_div($text{'leases_logs_desc'});
|
|
&print_recent_logs();
|
|
print &ui_tabs_end_tab("mode", "logs");
|
|
|
|
print &ui_tabs_end(1);
|
|
&ui_print_footer("index.cgi", $text{'index_return'});
|
|
|
|
# print_active_leases(version)
|
|
# Renders active leases for one DHCP protocol version.
|
|
sub print_active_leases
|
|
{
|
|
my ($ver) = @_;
|
|
my ($leases, $err) = &kea_active_leases($ver);
|
|
print &ui_subheading(&text('comp_dhcp'.$ver));
|
|
&print_lease_error_notice($err);
|
|
return if ($err);
|
|
if (!@$leases) {
|
|
print &ui_p(&text('leases_none', $ver));
|
|
return;
|
|
}
|
|
|
|
# Lease CSV files use different columns across DHCPv4/DHCPv6 and Kea versions;
|
|
# these helpers normalize the common fields administrators need most.
|
|
print &ui_columns_start([
|
|
$text{'col_address'},
|
|
$text{'col_id'},
|
|
$text{'col_identifier'},
|
|
$text{'col_hostname'},
|
|
$text{'col_expires'},
|
|
$text{'col_state'},
|
|
], 100);
|
|
foreach my $lease (@$leases) {
|
|
print &ui_columns_row([
|
|
&html_escape(&kea_lease_address($lease)),
|
|
&html_escape($lease->{'subnet_id'} || ""),
|
|
&html_escape(&kea_lease_identifier($lease)),
|
|
&html_escape($lease->{'hostname'} || ""),
|
|
&html_escape(&kea_lease_expires($lease)),
|
|
&html_escape(&kea_lease_state($lease)),
|
|
]);
|
|
}
|
|
print &ui_columns_end();
|
|
}
|
|
|
|
# print_pool_usage(version)
|
|
# Renders configured subnet pool counts beside active lease counts.
|
|
sub print_pool_usage
|
|
{
|
|
my ($ver) = @_;
|
|
my ($rows, $err) = &kea_pool_usage_rows($ver);
|
|
print &ui_subheading(&text('comp_dhcp'.$ver));
|
|
if ($err) {
|
|
print &ui_alert_box(&html_escape($err), "warning", undef, undef, "");
|
|
return;
|
|
}
|
|
if (!@$rows) {
|
|
print &ui_p(&text('leases_no_subnets', $ver));
|
|
return;
|
|
}
|
|
|
|
# This is intentionally per-subnet rather than per-range: Kea pools can be
|
|
# ranges, prefixes, and delegated prefix pools, and active lease CSV files only
|
|
# reliably tie leases back to subnet IDs.
|
|
print &ui_columns_start([
|
|
$text{'col_id'},
|
|
$text{'col_subnet'},
|
|
$text{'col_pools'},
|
|
$text{'col_pd_pools'},
|
|
$text{'col_reservations'},
|
|
$text{'col_active_leases'},
|
|
], 100);
|
|
foreach my $row (@$rows) {
|
|
print &ui_columns_row([
|
|
&html_escape($row->{'id'}),
|
|
&html_escape($row->{'subnet'}),
|
|
$row->{'pools'},
|
|
$row->{'pd_pools'},
|
|
$row->{'reservations'},
|
|
$row->{'active'},
|
|
]);
|
|
}
|
|
print &ui_columns_end();
|
|
}
|
|
|
|
# print_lease_statistics()
|
|
# Renders lease-file counters for DHCPv4 and DHCPv6.
|
|
sub print_lease_statistics
|
|
{
|
|
print &ui_columns_start([
|
|
$text{'col_service'},
|
|
$text{'col_active_leases'},
|
|
$text{'col_total'},
|
|
$text{'col_inactive'},
|
|
$text{'col_file'},
|
|
$text{'col_summary'},
|
|
], 100);
|
|
foreach my $ver (4, 6) {
|
|
my $s = &kea_lease_summary($ver);
|
|
print &ui_columns_row([
|
|
&html_escape(&text('comp_dhcp'.$ver)),
|
|
$s->{'active'},
|
|
$s->{'total'},
|
|
$s->{'inactive'},
|
|
&sane_file_cell($s->{'file'}),
|
|
&html_escape($s->{'error'} || ""),
|
|
]);
|
|
}
|
|
print &ui_columns_end();
|
|
}
|
|
|
|
# print_recent_logs()
|
|
# Renders recent journal entries for configured Kea services.
|
|
sub print_recent_logs
|
|
{
|
|
print &ui_columns_start([
|
|
$text{'col_service'},
|
|
$text{'col_logs'},
|
|
], 100, 0, [ "width=20%", "width=80%" ]);
|
|
foreach my $c (&kea_components()) {
|
|
my $logs = &kea_recent_component_log_lines($c, 20);
|
|
my $body = @$logs ? join(&ui_br(), map { &html_escape($_) } @$logs) :
|
|
&html_escape($text{'leases_no_logs'});
|
|
print &ui_columns_row([
|
|
&html_escape($c->{'label'}),
|
|
$body,
|
|
]);
|
|
}
|
|
print &ui_columns_end();
|
|
}
|
|
|
|
# print_lease_error_notice(error)
|
|
# Shows non-fatal lease-file read errors for one active-lease table.
|
|
sub print_lease_error_notice
|
|
{
|
|
my ($err) = @_;
|
|
print &ui_alert_box(&html_escape($err), "warning", undef, undef, "") if ($err);
|
|
}
|
|
|
|
# sane_file_cell(file)
|
|
# Formats a configured file path for display without assuming it exists.
|
|
sub sane_file_cell
|
|
{
|
|
my ($file) = @_;
|
|
return "" if (!$file);
|
|
return &ui_tag('tt', &html_escape($file));
|
|
}
|