]> git.proxmox.com Git - pve-firewall.git/blame - test/fwtester.pl
clone_vmfw_conf: lock new config
[pve-firewall.git] / test / fwtester.pl
CommitLineData
f1bafd37
DM
1#!/usr/bin/perl
2
3use lib '../src';
fdbdbf60 4
f1bafd37
DM
5use strict;
6use warnings;
fdbdbf60 7
f1bafd37 8use Data::Dumper;
ec2e28f6 9use File::Basename;
fdbdbf60 10use Getopt::Long;
680d56ee 11use Net::IP;
f1bafd37 12
fdbdbf60
TL
13use PVE::Corosync;
14use PVE::FirewallSimulator;
15use PVE::INotify;
16
d1486f38
DM
17my $debug = 0;
18
ec2e28f6
DM
19sub print_usage_and_exit {
20 die "usage: $0 [--debug] [testfile [testid]]\n";
21}
22
23if (!GetOptions ('debug' => \$debug)) {
24 print_usage_and_exit();
25}
26
6f6a6b3f
SR
27# load dummy corosync config to have fw create according rules
28my $corosync_conf_fn = "corosync.conf";
29my $raw = PVE::Tools::file_get_contents($corosync_conf_fn);
30my $local_hostname = PVE::INotify::nodename();
31(my $raw_replaced = $raw) =~ s/proxself$/$local_hostname\n/gm;
32my $corosync_conf = PVE::Corosync::parse_conf($corosync_conf_fn, $raw_replaced);
33
63e8c70e 34PVE::FirewallSimulator::debug($debug);
fdbdbf60 35
ec2e28f6
DM
36my $testfilename = shift;
37my $testid = shift;
38
f1bafd37 39sub run_tests {
ec2e28f6
DM
40 my ($vmdata, $testdir, $testfile, $testid) = @_;
41
42 $testfile = 'tests' if !$testfile;
f1bafd37 43
63e8c70e 44
f1bafd37
DM
45 $vmdata->{testdir} = $testdir;
46
63e8c70e
DM
47 my $host_ip = '172.16.1.2';
48
525778d7 49 PVE::Firewall::local_network('172.16.1.0/24');
ee06b009 50
f1bafd37 51 my ($ruleset, $ipset_ruleset) =
6f6a6b3f 52 PVE::Firewall::compile(undef, undef, $vmdata, $corosync_conf);
f1bafd37 53
ec2e28f6
DM
54 my $filename = "$testdir/$testfile";
55 my $fh = IO::File->new($filename) ||
56 die "unable to open '$filename' - $!\n";
f1bafd37 57
ec2e28f6 58 my $testcount = 0;
f1bafd37
DM
59 while (defined(my $line = <$fh>)) {
60 next if $line =~ m/^\s*$/;
61 next if $line =~ m/^#.*$/;
62 if ($line =~ m/^\{.*\}\s*$/) {
63 my $test = eval $line;
64 die $@ if $@;
ec2e28f6 65 next if defined($testid) && (!defined($test->{id}) || ($testid ne $test->{id}));
63e8c70e 66 PVE::FirewallSimulator::reset_trace();
64e0adf4 67 print Dumper($ruleset->{filter}) if $debug;
ec2e28f6 68 $testcount++;
1352eaa1
DM
69 eval {
70 my @test_zones = qw(host outside nfvm vm100 ct200);
71 if (!defined($test->{from}) && !defined($test->{to})) {
72 die "missing zone speification (from, to)\n";
73 } elsif (!defined($test->{to})) {
74 foreach my $zone (@test_zones) {
75 next if $zone eq $test->{from};
76 $test->{to} = $zone;
63e8c70e 77 PVE::FirewallSimulator::add_trace("Set Zone: to => '$zone'\n");
64e0adf4 78 PVE::FirewallSimulator::simulate_firewall($ruleset->{filter}, $ipset_ruleset,
63e8c70e 79 $host_ip, $vmdata, $test);
1352eaa1
DM
80 }
81 } elsif (!defined($test->{from})) {
82 foreach my $zone (@test_zones) {
83 next if $zone eq $test->{to};
84 $test->{from} = $zone;
63e8c70e 85 PVE::FirewallSimulator::add_trace("Set Zone: from => '$zone'\n");
64e0adf4 86 PVE::FirewallSimulator::simulate_firewall($ruleset->{filter}, $ipset_ruleset,
63e8c70e 87 $host_ip, $vmdata, $test);
1352eaa1
DM
88 }
89 } else {
64e0adf4 90 PVE::FirewallSimulator::simulate_firewall($ruleset->{filter}, $ipset_ruleset,
63e8c70e 91 $host_ip, $vmdata, $test);
1352eaa1
DM
92 }
93 };
f1bafd37
DM
94 if (my $err = $@) {
95
64e0adf4 96 print Dumper($ruleset->{filter}) if !$debug;
f1bafd37 97
63e8c70e 98 print PVE::FirewallSimulator::get_trace() . "\n" if !$debug;
f1bafd37 99
ec2e28f6 100 print "$filename line $.: $line";
f1bafd37
DM
101
102 print "test failed: $err\n";
103
104 exit(-1);
105 }
106 } else {
107 die "parse error";
108 }
109 }
110
ec2e28f6
DM
111 die "no tests found\n" if $testcount <= 0;
112
113 print "PASS: $filename\n";
f1bafd37
DM
114
115 return undef;
116}
117
118my $vmdata = {
119 qemu => {
120 100 => {
db990d66 121 net0 => "e1000=0E:0B:38:B8:B3:21,bridge=vmbr0,firewall=1",
66f33d78
DM
122 net1 => "e1000=0E:0B:38:B9:B4:21,bridge=vmbr1,firewall=1",
123 net2 => "e1000=0E:0B:38:BA:B4:21,bridge=vmbr2,firewall=1",
d1486f38
DM
124 },
125 101 => {
db990d66 126 net0 => "e1000=0E:0B:38:B8:B3:22,bridge=vmbr0,firewall=1",
d1486f38
DM
127 },
128 # on bridge vmbr1
129 110 => {
db990d66 130 net0 => "e1000=0E:0B:38:B8:B4:21,bridge=vmbr1,firewall=1",
f1bafd37
DM
131 },
132 },
e038c485 133 lxc => {
f1bafd37 134 200 => {
e038c485 135 net0 => "name=eth0,hwaddr=0E:18:24:41:2C:43,bridge=vmbr0,firewall=1,ip=10.0.200.1/24",
f1bafd37 136 },
d1486f38 137 201 => {
e038c485 138 net0 => "name=eth0,hwaddr=0E:18:24:41:2C:44,bridge=vmbr0,firewall=1,ip=10.0.200.2/24",
d1486f38 139 },
f1bafd37
DM
140 },
141};
142
ec2e28f6
DM
143if ($testfilename) {
144 my $testfile;
145 my $dir;
146
147 if (-d $testfilename) {
148 $dir = $testfilename;
149 } elsif (-f $testfilename) {
150 $dir = dirname($testfilename);
151 $testfile = basename($testfilename);
152 } else {
153 die "no such file/dir '$testfilename'\n";
154 }
155
156 run_tests($vmdata, $dir, $testfile, $testid);
157
158} else {
159 foreach my $dir (<test-*>) {
160 next if ! -d $dir;
161 run_tests($vmdata, $dir);
162 }
f1bafd37
DM
163}
164
165print "OK - all tests passed\n";
166
167exit(0);