mirror of
https://github.com/webmin/webmin.git
synced 2026-05-06 15:20:29 +01:00
Re-order rules support
This commit is contained in:
BIN
images/icon.gif
Normal file
BIN
images/icon.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
29
index.cgi
29
index.cgi
@@ -87,21 +87,36 @@ if (!@tables) {
|
||||
my @rules = grep { $_->{'chain'} eq $c } @{$curr->{'rules'}};
|
||||
my $rules_html_row;
|
||||
if (@rules) {
|
||||
my @rows;
|
||||
my $ri = 0;
|
||||
$rules_html_row = "<table class='nftables_rules_table' width='100%'>\n";
|
||||
foreach my $r (@rules) {
|
||||
my $desc = &describe_rule($r);
|
||||
push(@rows, &ui_link(
|
||||
my $rule_link = &ui_link(
|
||||
"edit_rule.cgi?table=$in{'table'}&chain=".
|
||||
&urlize($c)."&idx=$r->{'index'}",
|
||||
$desc));
|
||||
$desc);
|
||||
my $move = &ui_up_down_arrows(
|
||||
"move_rule.cgi?table=$in{'table'}&chain=".
|
||||
&urlize($c)."&idx=$r->{'index'}&dir=up",
|
||||
"move_rule.cgi?table=$in{'table'}&chain=".
|
||||
&urlize($c)."&idx=$r->{'index'}&dir=down",
|
||||
$ri > 0,
|
||||
$ri < $#rules);
|
||||
$rules_html_row .= "<tr><td>$rule_link</td>".
|
||||
"<td align='right' style='white-space:nowrap'>$move</td></tr>\n";
|
||||
$ri++;
|
||||
}
|
||||
$rules_html_row = join("<br>", @rows);
|
||||
$rules_html_row .= "<tr><td colspan='2'>".
|
||||
&ui_link("edit_rule.cgi?table=$in{'table'}&chain=".
|
||||
&urlize($c)."&new=1", $text{'index_radd'}).
|
||||
"</td></tr>\n";
|
||||
$rules_html_row .= "</table>";
|
||||
} else {
|
||||
$rules_html_row = "<i>$text{'index_rules_none'}</i>";
|
||||
$rules_html_row .= "<br>".
|
||||
&ui_link("edit_rule.cgi?table=$in{'table'}&chain=".
|
||||
&urlize($c)."&new=1", $text{'index_radd'});
|
||||
}
|
||||
$rules_html_row .= "<br>".
|
||||
&ui_link("edit_rule.cgi?table=$in{'table'}&chain=".
|
||||
&urlize($c)."&new=1", $text{'index_radd'});
|
||||
|
||||
my $actions_html =
|
||||
&ui_link("edit_chain.cgi?table=$in{'table'}&chain=".
|
||||
|
||||
5
lang/en
5
lang/en
@@ -177,3 +177,8 @@ save_failed=Failed to save rule: <pre>$1</pre>
|
||||
save_raw_empty=Raw rule cannot be empty.
|
||||
save_raw_multiline=Raw rule must be a single line.
|
||||
save_invalid_rule=Raw rule is invalid: $1
|
||||
move_err=Failed to move rule
|
||||
move_failed=Failed to move rule: <pre>$1</pre>
|
||||
move_notable=No such table selected
|
||||
move_nochain=No such chain selected
|
||||
move_norule=No such rule selected
|
||||
|
||||
40
move_rule.cgi
Executable file
40
move_rule.cgi
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/perl
|
||||
# move_rule.cgi
|
||||
# Move a rule up or down within a chain
|
||||
|
||||
require './nftables-lib.pl';
|
||||
use strict;
|
||||
use warnings;
|
||||
our (%in, %text);
|
||||
&ReadParse();
|
||||
&error_setup($text{'move_err'});
|
||||
|
||||
my @tables = &get_nftables_save();
|
||||
my $table = $tables[$in{'table'}];
|
||||
$table || &error($text{'move_notable'});
|
||||
|
||||
my $chain = $in{'chain'};
|
||||
$chain || &error($text{'move_nochain'});
|
||||
|
||||
my $dir = $in{'dir'};
|
||||
$dir = '' if (!defined($dir));
|
||||
|
||||
my $idx = $in{'idx'};
|
||||
$idx =~ /^\d+$/ || &error($text{'move_norule'});
|
||||
|
||||
my $rv = &move_rule_in_chain($table, $chain, $idx, $dir);
|
||||
if (!defined($rv)) {
|
||||
&error($text{'move_norule'});
|
||||
}
|
||||
|
||||
if ($rv) {
|
||||
my $err = &save_configuration(@tables);
|
||||
&error(&text('move_failed', $err)) if ($err);
|
||||
&webmin_log("move", "rule", undef,
|
||||
{ 'table' => $table->{'name'},
|
||||
'family' => $table->{'family'},
|
||||
'chain' => $chain,
|
||||
'dir' => $dir });
|
||||
}
|
||||
|
||||
&redirect("index.cgi?table=$in{'table'}");
|
||||
@@ -191,6 +191,56 @@ if (defined($type) || defined($hook) || defined($priority) || defined($policy))
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub move_rule_in_chain
|
||||
{
|
||||
my ($table, $chain, $idx, $dir) = @_;
|
||||
return undef if (!defined($table) || ref($table) ne 'HASH');
|
||||
return undef if (!defined($idx) || $idx !~ /^\d+$/);
|
||||
return undef if (!defined($chain) || $chain eq '');
|
||||
return undef if (!$table->{'rules'} || ref($table->{'rules'}) ne 'ARRAY');
|
||||
return undef if ($idx > $#{$table->{'rules'}});
|
||||
my $rule = $table->{'rules'}->[$idx];
|
||||
return undef if (!$rule || $rule->{'chain'} ne $chain);
|
||||
|
||||
my @chain_idxs;
|
||||
for (my $i = 0; $i < @{$table->{'rules'}}; $i++) {
|
||||
my $r = $table->{'rules'}->[$i];
|
||||
next if (!$r || ref($r) ne 'HASH');
|
||||
push(@chain_idxs, $i) if ($r->{'chain'} && $r->{'chain'} eq $chain);
|
||||
}
|
||||
my $pos;
|
||||
for (my $i = 0; $i <= $#chain_idxs; $i++) {
|
||||
if ($chain_idxs[$i] == $idx) {
|
||||
$pos = $i;
|
||||
last;
|
||||
}
|
||||
}
|
||||
return undef if (!defined($pos));
|
||||
|
||||
my $swap;
|
||||
if ($dir eq 'up') {
|
||||
return 0 if ($pos == 0);
|
||||
$swap = $chain_idxs[$pos-1];
|
||||
}
|
||||
elsif ($dir eq 'down') {
|
||||
return 0 if ($pos == $#chain_idxs);
|
||||
$swap = $chain_idxs[$pos+1];
|
||||
}
|
||||
else {
|
||||
return undef;
|
||||
}
|
||||
|
||||
($table->{'rules'}->[$idx], $table->{'rules'}->[$swap]) =
|
||||
($table->{'rules'}->[$swap], $table->{'rules'}->[$idx]);
|
||||
|
||||
for (my $i = 0; $i < @{$table->{'rules'}}; $i++) {
|
||||
my $r = $table->{'rules'}->[$i];
|
||||
$r->{'index'} = $i if ($r && ref($r) eq 'HASH');
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub format_addr_expr
|
||||
{
|
||||
my ($dir, $rule) = @_;
|
||||
|
||||
@@ -135,4 +135,28 @@ ok(!&validate_chain_base('filter', 'input', undef, 'accept'),
|
||||
ok(&validate_chain_base(undef, undef, undef, undef),
|
||||
'chain base none set valid');
|
||||
|
||||
my $table_move = {
|
||||
rules => [
|
||||
{ chain => 'input', index => 0, text => 'r0' },
|
||||
{ chain => 'input', index => 1, text => 'r1' },
|
||||
{ chain => 'forward', index => 2, text => 'r2' },
|
||||
{ chain => 'input', index => 3, text => 'r3' },
|
||||
],
|
||||
};
|
||||
ok(&move_rule_in_chain($table_move, 'input', 1, 'down'),
|
||||
'move rule down returns true');
|
||||
is($table_move->{rules}->[1]->{text}, 'r3', 'rule moved down in array');
|
||||
is($table_move->{rules}->[3]->{text}, 'r1', 'rule swapped down in array');
|
||||
is($table_move->{rules}->[1]->{index}, 1, 'moved rule index updated');
|
||||
is($table_move->{rules}->[3]->{index}, 3, 'swapped rule index updated');
|
||||
|
||||
my $table_move2 = {
|
||||
rules => [
|
||||
{ chain => 'input', index => 0, text => 'r0' },
|
||||
{ chain => 'input', index => 1, text => 'r1' },
|
||||
],
|
||||
};
|
||||
is(&move_rule_in_chain($table_move2, 'input', 0, 'up'), 0,
|
||||
'top rule cannot move up');
|
||||
|
||||
done_testing();
|
||||
|
||||
Reference in New Issue
Block a user