]> git.proxmox.com Git - pve-firewall.git/blame - src/PVE/Firewall/Helpers.pm
api: Add optional parameters `since` and `until` for timestamp filter
[pve-firewall.git] / src / PVE / Firewall / Helpers.pm
CommitLineData
5bdc31fb
AD
1package PVE::Firewall::Helpers;
2
3use strict;
4use warnings;
5
8bd9b3e4
CE
6use Date::Parse qw(str2time);
7use Errno qw(ENOENT);
8use File::Basename qw(fileparse);
9use IO::Zlib;
21d5ba9c 10use PVE::Cluster;
5bdc31fb
AD
11use PVE::Tools qw(file_get_contents file_set_contents);
12
13use base 'Exporter';
14our @EXPORT_OK = qw(
21d5ba9c 15lock_vmfw_conf
5bdc31fb
AD
16remove_vmfw_conf
17clone_vmfw_conf
18);
19
20my $pvefw_conf_dir = "/etc/pve/firewall";
21
21d5ba9c
TL
22sub lock_vmfw_conf {
23 my ($vmid, $timeout, $code, @param) = @_;
24
25 die "can't lock VM firewall config for undefined VMID\n"
26 if !defined($vmid);
27
28 my $res = PVE::Cluster::cfs_lock_firewall("vm-$vmid", $timeout, $code, @param);
29 die $@ if $@;
30
31 return $res;
32}
33
5bdc31fb
AD
34sub remove_vmfw_conf {
35 my ($vmid) = @_;
36
37 my $vmfw_conffile = "$pvefw_conf_dir/$vmid.fw";
38
39 unlink $vmfw_conffile;
40}
41
42sub clone_vmfw_conf {
43 my ($vmid, $newid) = @_;
44
45 my $sourcevm_conffile = "$pvefw_conf_dir/$vmid.fw";
46 my $clonevm_conffile = "$pvefw_conf_dir/$newid.fw";
47
48 lock_vmfw_conf($newid, 10, sub {
49 if (-f $clonevm_conffile) {
50 unlink $clonevm_conffile;
51 }
52 if (-f $sourcevm_conffile) {
53 my $data = file_get_contents($sourcevm_conffile);
54 file_set_contents($clonevm_conffile, $data);
55 }
56 });
57}
58
8bd9b3e4
CE
59sub dump_fw_logfile {
60 my ($filename, $param, $callback) = @_;
61 my ($start, $limit, $since, $until) = $param->@{qw(start limit since until)};
62
63 my $filter = sub {
64 my ($line) = @_;
65
66 if (defined($callback)) {
67 return undef if !$callback->($line);
68 }
69
70 if ($since || $until) {
71 my @words = split / /, $line;
72 my $timestamp = str2time($words[3], $words[4]);
73 return undef if $since && $timestamp < $since;
74 return undef if $until && $timestamp > $until;
75 }
76
77 return $line;
78 };
79
80 if (!defined($since) && !defined($until)) {
81 return PVE::Tools::dump_logfile($filename, $start, $limit, $filter);
82 }
83
84 my %state = (
85 'count' => 0,
86 'lines' => [],
87 'start' => $start,
88 'limit' => $limit,
89 );
90
91 # Take into consideration also rotated logs
92 my ($basename, $logdir, $type) = fileparse($filename);
93 my $regex = qr/^\Q$basename\E(\.[\d]+(\.gz)?)?$/;
94 my @files = ();
95
96 PVE::Tools::dir_glob_foreach($logdir, $regex, sub {
97 my ($file) = @_;
98 push @files, $file;
99 });
100
101 @files = reverse sort @files;
102
103 my $filecount = 0;
104 for my $filename (@files) {
105 $state{'final'} = $filecount == $#files;
106 $filecount++;
107
108 my $fh;
109 if ($filename =~ /\.gz$/) {
110 $fh = IO::Zlib->new($logdir.$filename, "r");
111 } else {
112 $fh = IO::File->new($logdir.$filename, "r");
113 }
114
115 if (!$fh) {
116 # If file vanished since reading dir entries, ignore
117 next if $!{ENOENT};
118
119 my $lines = $state{'lines'};
120 my $count = ++$state{'count'};
121 push @$lines, ($count, { n => $count, t => "unable to open file - $!"});
122 last;
123 }
124
125 PVE::Tools::dump_logfile_by_filehandle($fh, $filter, \%state);
126
127 close($fh);
128 }
129
130 return ($state{'count'}, $state{'lines'});
131}
132
21d5ba9c 1331;