]> git.proxmox.com Git - pmg-api.git/blob - PMG/Config.pm
add more configuration properties, new helper get_section()
[pmg-api.git] / PMG / Config.pm
1 package PMG::Config::Base;
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6
7 use PVE::Tools;
8 use PVE::JSONSchema qw(get_standard_option);
9 use PVE::SectionConfig;
10
11 use base qw(PVE::SectionConfig);
12
13 my $defaultData = {
14 propertyList => {
15 type => { description => "Section type." },
16 section_id => {
17 description => "Secion ID.",
18 type => 'string', format => 'pve-configid',
19 },
20 },
21 };
22
23 sub private {
24 return $defaultData;
25 }
26
27 sub format_section_header {
28 my ($class, $type, $sectionId) = @_;
29
30 if ($type eq 'ldap') {
31 $sectionId =~ s/^ldap_//;
32 return "$type: $sectionId\n";
33 } else {
34 return "section: $type\n";
35 }
36 }
37
38
39 sub parse_section_header {
40 my ($class, $line) = @_;
41
42 if ($line =~ m/^(ldap|section):\s*(\S+)\s*$/) {
43 my ($raw_type, $raw_id) = (lc($1), $2);
44 my $type = $raw_type eq 'section' ? $raw_id : $raw_type;
45 my $section_id = "${raw_type}_${raw_id}";
46 my $errmsg = undef; # set if you want to skip whole section
47 eval { PVE::JSONSchema::pve_verify_configid($raw_id); };
48 $errmsg = $@ if $@;
49 my $config = {}; # to return additional attributes
50 return ($type, $section_id, $errmsg, $config);
51 }
52 return undef;
53 }
54
55 package PMG::Config::Administration;
56
57 use strict;
58 use warnings;
59
60 use base qw(PMG::Config::Base);
61
62 sub type {
63 return 'administration';
64 }
65
66 sub properties {
67 return {
68 dailyreport => {
69 description => "Send daily reports.",
70 type => 'boolean',
71 default => 1,
72 },
73 demo => {
74 description => "Demo mode - do not start SMTP filter.",
75 type => 'boolean',
76 default => 0,
77 },
78 email => {
79 description => "Administrator E-Mail address.",
80 type => 'string', format => 'email',
81 default => 'admin@domain.tld',
82 }
83 };
84 }
85
86 sub options {
87 return {
88 dailyreport => { optional => 1 },
89 demo => { optional => 1 },
90 };
91 }
92
93 package PMG::Config::Spam;
94
95 use strict;
96 use warnings;
97
98 use base qw(PMG::Config::Base);
99
100 sub type {
101 return 'spam';
102 }
103
104 sub properties {
105 return {
106 languages => {
107 description => "This option is used to specify which languages are considered OK for incoming mail.",
108 type => 'string',
109 pattern => '(all|([a-z][a-z])+( ([a-z][a-z])+)*)',
110 default => 'all',
111 },
112 use_bayes => {
113 description => "Whether to use the naive-Bayesian-style classifier.",
114 type => 'boolean',
115 default => 1,
116 },
117 wl_bounce_relays => {
118 description => "Whitelist legitimate bounce relays.",
119 type => 'string',
120 },
121 bounce_score => {
122 description => "Additional score for bounce mails.",
123 type => 'integer',
124 minimum => 0,
125 maximum => 1000,
126 default => 0,
127 },
128 rbl_checks => {
129 description => "Enable real time blacklists (RBL) checks.",
130 type => 'boolean',
131 default => 1,
132 },
133 maxspamsize => {
134 description => "Maximum size of spam messages in bytes.",
135 type => 'integer',
136 minimim => 64,
137 default => 200*1024,
138 },
139 };
140 }
141
142 sub options {
143 return {
144 wl_bounce_relays => { optional => 1 },
145 languages => { optional => 1 },
146 use_bayes => { optional => 1 },
147 bounce_score => { optional => 1 },
148 rbl_checks => { optional => 1 },
149 maxspamsize => { optional => 1 },
150 };
151 }
152
153 package PMG::Config::ClamAV;
154
155 use strict;
156 use warnings;
157
158 use base qw(PMG::Config::Base);
159
160 sub type {
161 return 'clamav';
162 }
163
164 sub properties {
165 return {
166 archivemaxfiles => {
167 description => "Number of files to be scanned within an archive.",
168 type => 'integer',
169 minimum => 0,
170 default => 1000,
171 },
172 };
173 }
174
175 sub options {
176 return {
177 archivemaxfiles => { optional => 1 },
178 };
179 }
180
181 package PMG::Config::LDAP;
182
183 use strict;
184 use warnings;
185
186 use base qw(PMG::Config::Base);
187
188 sub type {
189 return 'ldap';
190 }
191
192 sub properties {
193 return {
194 mode => {
195 description => "LDAP protocol mode ('ldap' or 'ldaps').",
196 type => 'string',
197 enum => ['ldap', 'ldaps'],
198 default => 'ldap',
199 },
200 };
201 }
202
203 sub options {
204 return {
205 mode => { optional => 1 },
206 };
207 }
208
209 package PMG::Config::Mail;
210
211 use strict;
212 use warnings;
213
214 use PVE::ProcFSTools;
215
216 use base qw(PMG::Config::Base);
217
218 sub type {
219 return 'mail';
220 }
221
222 my $physicalmem = 0;
223 sub physical_memory {
224
225 return $physicalmem if $physicalmem;
226
227 my $info = PVE::ProcFSTools::read_meminfo();
228 my $total = int($info->{memtotal} / (1024*1024));
229
230 return $total;
231 }
232
233 sub get_max_filters {
234 # estimate optimal number of filter servers
235
236 my $max_servers = 5;
237 my $servermem = 120;
238 my $memory = physical_memory();
239 my $add_servers = int(($memory - 512)/$servermem);
240 $max_servers += $add_servers if $add_servers > 0;
241 $max_servers = 40 if $max_servers > 40;
242
243 return $max_servers - 2;
244 }
245
246 sub properties {
247 return {
248 banner => {
249 description => "ESMTP banner.",
250 type => 'string',
251 maxLength => 1024,
252 default => 'ESMTP Proxmox',
253 },
254 max_filters => {
255 description => "Maximum number of filter processes.",
256 type => 'integer',
257 minimum => 3,
258 maximum => 40,
259 default => get_max_filters(),
260 },
261 hide_received => {
262 description => "Hide received header in outgoing mails.",
263 type => 'boolean',
264 degault => 0,
265 },
266 };
267 }
268
269 sub options {
270 return {
271 banner => { optional => 1 },
272 max_filters => { optional => 1 },
273 hide_received => { optional => 1 },
274 };
275 }
276 package PMG::Config;
277
278 use strict;
279 use warnings;
280
281 use Data::Dumper;
282
283 use PVE::Tools;
284 use PVE::INotify;
285
286 PMG::Config::Administration->register();
287 PMG::Config::Mail->register();
288 PMG::Config::Spam->register();
289 PMG::Config::LDAP->register();
290 PMG::Config::ClamAV->register();
291
292 # initialize all plugins
293 PMG::Config::Base->init();
294
295
296 sub new {
297 my ($type) = @_;
298
299 my $class = ref($type) || $type;
300
301 my $cfg = PVE::INotify::read_file("pmg.conf");
302
303 return bless $cfg, $class;
304 }
305
306 # get section value or default
307 # this does not work for ldap entries
308 sub get {
309 my ($self, $section, $key) = @_;
310
311 my $pdata = PMG::Config::Base->private();
312 return undef if !defined($pdata->{options}->{$section});
313 return undef if !defined($pdata->{options}->{$section}->{$key});
314 my $pdesc = $pdata->{propertyList}->{$key};
315 return undef if !defined($pdesc);
316
317 my $configid = "section_$section";
318 if (defined($self->{ids}->{$configid}) &&
319 defined(my $value = $self->{ids}->{$configid}->{$key})) {
320 return $value;
321 }
322
323 return $pdesc->{default};
324 }
325
326 # get a whole section with default value
327 # this does not work for ldap entries
328 sub get_section {
329 my ($self, $section) = @_;
330
331 my $pdata = PMG::Config::Base->private();
332 return undef if !defined($pdata->{options}->{$section});
333
334 my $res = {};
335
336 foreach my $key (keys %{$pdata->{options}->{$section}}) {
337
338 my $pdesc = $pdata->{propertyList}->{$key};
339
340 my $configid = "section_$section";
341 if (defined($self->{ids}->{$configid}) &&
342 defined(my $value = $self->{ids}->{$configid}->{$key})) {
343 $res->{$key} = $value;
344 next;
345 }
346 $res->{$key} = $pdesc->{default};
347 }
348
349 return $res;
350 }
351
352 sub read_pmg_conf {
353 my ($filename, $fh) = @_;
354
355 local $/ = undef; # slurp mode
356
357 my $raw = <$fh>;
358
359 return PMG::Config::Base->parse_config($filename, $raw);
360 }
361
362 sub write_pmg_conf {
363 my ($filename, $fh, $cfg) = @_;
364
365 my $raw = PMG::Config::Base->write_config($filename, $cfg);
366
367 PVE::Tools::safe_print($filename, $fh, $raw);
368 }
369
370 PVE::INotify::register_file('pmg.conf', "/etc/proxmox/pmg.conf",
371 \&read_pmg_conf,
372 \&write_pmg_conf);
373
374
375 1;