root/test/t/testconfig.pm

Revision 49b8645cf26c988d8416168333196b86d7a99204, 15.9 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 4 years ago)

filtersets are required

  • Property mode set to 100644
Line 
1 package testconfig;
2 use Test::More;
3 use Fcntl;
4 use DBI;
5 use Cwd;
6 use Exporter 'import';
7 use Data::Dumper;
8 use strict;
9 use vars qw/@EXPORT/;
10
11 my $noit_pid = 0;
12 my $stratcon_pid = 0;
13
14
15 @EXPORT = qw($NOIT_TEST_DB $NOIT_TEST_DB_PORT
16              $NOIT_API_PORT $NOIT_CLI_PORT
17              $STRATCON_API_PORT $STRATCON_CLI_PORT
18              pg make_noit_config start_noit stop_noit
19              make_stratcon_config start_stratcon stop_stratcon
20              $MODULES_DIR $LUA_DIR $all_noit_modules $all_stratcon_modules);
21
22 our $default_filterset = {
23   allowall => [ { type => "allow" } ],
24 };
25 our $all_noit_modules = {
26   'selfcheck' => { 'image' => 'selfcheck' },
27   'ping_icmp' => { 'image' => 'ping_icmp' },
28   'snmp' => { 'image' => 'snmp' },
29   'ssh2' => { 'image' => 'ssh2' },
30   'mysql' => { 'image' => 'mysql' },
31   'postgres' => { 'image' => 'postgres' },
32   'varnish' => { 'loader' => 'lua', 'object' => 'noit.module.varnish' },
33   'http' => { 'loader' => 'lua', 'object' => 'noit.module.http' },
34   'resmon' => { 'loader' => 'lua', 'object' => 'noit.module.resmon' },
35   'smtp' => { 'loader' => 'lua', 'object' => 'noit.module.smtp' },
36   'tcp' => { 'loader' => 'lua', 'object' => 'noit.module.tcp' },
37 };
38
39 our $NOIT_TEST_DB = "/tmp/noit-test-db";
40 our $NOIT_TEST_DB_PORT = 23816;
41 our $NOIT_API_PORT = 42364;
42 our $NOIT_CLI_PORT = 42365;
43 our $STRATCON_API_PORT = 42366;
44 our $STRATCON_CLI_PORT = 42367;
45 our $STRATCON_WEB_PORT = 42368;
46
47 our ($MODULES_DIR, $LUA_DIR);
48
49 sub pg {
50   my $db = shift || 'postgres';
51   my $user = shift || $ENV{USER};
52   return DBI->connect(
53     "dbi:Pg:host=localhost;port=$NOIT_TEST_DB_PORT;database=$db", $user, ''
54   );
55 }
56
57 sub make_eventer_config {
58   my ($o, $opts) = @_;
59   my $cwd = $opts->{cwd};
60   $opts->{eventer_config}->{default_queue_threads} ||= 10;
61   $opts->{eventer_config}->{default_ca_chain} ||= "$cwd/../test-ca.crt";
62   print $o qq{
63   <eventer>
64     <config>
65       <default_queue_threads>$opts->{eventer_config}->{default_queue_threads}</default_queue_threads>
66       <default_ca_chain>$opts->{eventer_config}->{default_ca_chain}</default_ca_chain>
67     </config>
68   </eventer>
69 };
70 }
71 sub make_rest_acls {
72   my ($o, $opts) = @_;
73   my $acls = $opts->{rest_acls};
74   print $o qq{  <rest>\n};
75   foreach my $acl (@$acls) {
76     print $o qq^    <acl^;
77     print $o qq^ type="$acl->{type}"^ if exists($acl->{type});
78     print $o qq^ cn="$acl->{cn}"^ if exists($acl->{cn});
79     print $o qq^ url="$acl->{url}"^ if exists($acl->{url});
80     print $o qq^>\n^;
81     my $rules = $acl->{rules};
82     foreach my $rule (@$rules) {
83       print $o qq^      <rule^;
84       print $o qq^ type="$rule->{type}"^ if exists($rule->{type});
85       print $o qq^ cn="$rule->{cn}"^ if exists($rule->{cn});
86       print $o qq^ url="$rule->{url}"^ if exists($rule->{url});
87       print $o qq^/>\n^;
88     }
89     print $o qq^    </acl>\n^;
90   }
91   print $o qq{  </rest>\n};
92 }
93 sub make_log_section {
94   my ($o, $type, $dis) = @_;
95   print $o qq{      <$type>
96         <outlet name="$type"/>
97 };
98   while (my ($t, $d) = each %$dis) {
99     next unless length($t);
100     print $o qq{        <log name="$type/$t" disabled="$d"/>\n};
101   }
102   print $o qq{      </$type>\n};
103 }
104 sub make_logs_config {
105   my ($o, $opts) = @_;
106   my $cwd = $opts->{cwd};
107   my @logtypes = qw/collectd dns eventer external lua mysql ping_icmp postgres
108                     selfcheck snmp ssh2/;
109   # These are disabled attrs, so they look backwards
110   if(!exists($opts->{logs_error})) {
111     $opts->{logs_error}->{''} ||= 'false';
112   }
113   if(!exists($opts->{logs_debug})) {
114     $opts->{logs_debug}->{''} ||= 'true';
115   }
116   foreach(@logtypes) {
117     $opts->{logs_error}->{$_} ||= 'false';
118     $opts->{logs_debug}->{$_} ||= 'false';
119   }
120  
121   print $o qq{
122   <logs>
123     <console_output>
124       <outlet name="stderr"/>
125       <log name="error" disabled="$opts->{logs_error}->{''}"/>
126       <log name="debug" disabled="$opts->{logs_debug}->{''}"/>
127     </console_output>
128     <feeds>
129       <log name="feed" type="jlog" path="$cwd/logs/$opts->{name}.feed(stratcon)"/>
130     </feeds>
131     <components>
132 };
133   make_log_section($o, 'error', $opts->{logs_error});
134   make_log_section($o, 'debug', $opts->{logs_debug});
135   print $o qq{
136     </components>
137     <feeds>
138       <outlet name="feed"/>
139       <log name="check">
140         <outlet name="error"/>
141       </log>
142       <log name="status"/>
143       <log name="metrics"/>
144       <log name="config"/>
145     </feeds>
146   </logs>
147 };
148 }
149 sub make_modules_config {
150   my ($o, $opts) = @_;
151   my $cwd = $opts->{cwd};
152   print $o qq{
153   <modules directory="$cwd/../../src/modules">
154     <loader image="lua" name="lua">
155       <config><directory>$cwd/../../src/modules-lua/?.lua</directory></config>
156     </loader>
157 };
158   foreach(keys %{$opts->{generics}}) {
159     print $o qq{    <generic };
160     print $o qq{ image="$opts->{generics}->{$_}->{image}"}
161       if(exists($opts->{generics}->{$_}->{image}));
162     print $o qq{ name="$_"/>\n};
163   }
164   foreach(keys %{$opts->{modules}}) {
165     print $o qq{    <module };
166     print $o qq{ image="$opts->{modules}->{$_}->{image}"}
167       if(exists($opts->{modules}->{$_}->{image}));
168     print $o qq{ loader="$opts->{modules}->{$_}->{loader}"}
169       if(exists($opts->{modules}->{$_}->{loader}));
170     print $o qq{ object="$opts->{modules}->{$_}->{object}"}
171       if(exists($opts->{modules}->{$_}->{object}));
172     print $o qq{ name="$_"/>\n};
173   }
174   print $o qq{</modules>\n};
175 }
176 sub make_noit_listeners_config {
177   my ($o, $opts) = @_;
178   my $cwd = $opts->{cwd};
179   $opts->{noit_api_port} ||= $NOIT_API_PORT;
180   $opts->{noit_cli_port} ||= $NOIT_CLI_PORT;
181   print $o qq{
182   <listeners>
183     <sslconfig>
184       <optional_no_ca>false</optional_no_ca>
185       <certificate_file>$cwd/../test-noit.crt</certificate_file>
186       <key_file>$cwd/../test-noit.key</key_file>
187       <ca_chain>$cwd/../test-ca.crt</ca_chain>
188       <crl>$cwd/../test-ca.crl</crl>
189     </sslconfig>
190     <consoles type="noit_console">
191       <listener address="*" port="$opts->{noit_cli_port}">
192         <config>
193           <line_protocol>telnet</line_protocol>
194         </config>
195       </listener>
196     </consoles>
197     <listener type="control_dispatch" address="*" port="$opts->{noit_api_port}" ssl="on">
198       <config>
199         <log_transit_feed_name>feed</log_transit_feed_name>
200       </config>
201     </listener>
202   </listeners>
203 };
204 }
205 sub do_check_print {
206   my $o = shift;
207   my $list = shift;
208   return unless $list;
209   foreach my $node (@$list) {
210     print $o qq{<$node->[0]};
211     while(my ($k, $v) = each %{$node->[1]}) {
212       print $o qq{ $k="$v"};
213     }
214     if($node->[2]) {
215       print $o qq{>\n};
216       do_check_print($o, $node->[2]);
217       print $o qq{</check>\n};
218     }
219     else {
220       print $o qq{/>\n};
221     }
222   }
223 }
224 sub make_checks_config {
225   my ($o, $opts) = @_;
226   my $cwd = $opts->{cwd};
227   print $o qq{  <checks max_initial_stutter="1000" filterset="default">\n};
228   do_check_print($o, $opts->{checks});
229   print $o qq{  </checks>\n};
230 }
231 sub make_filtersets_config {
232   my ($o, $opts) = @_;
233   my $cwd = $opts->{cwd};
234   print $o qq{<filtersets>\n};
235   while (my ($name, $set) = each %{$opts->{filtersets}}) {
236     print $o qq{  <filterset name="$name">\n};
237     foreach my $rule (@$set) {
238       print $o qq{    <rule };
239       while(my ($k,$v) = each %$rule) {
240         print $o qq{ $k="$v"};
241       }
242       print $o qq{/>\n};
243     }
244     print $o qq{  </filterset>\n};
245   }
246   print $o qq{</filtersets>\n};
247 }
248
249 sub make_noit_config {
250   my $name = shift;
251   my $options = shift;
252   $options->{cwd} ||= cwd();
253   $options->{modules} = $all_noit_modules unless exists($options->{modules});
254   $options->{filtersets} = $default_filterset unless exists($options->{filtersets});
255   $options->{rest_acls} ||= [ { type => 'deny', rules => [ { type => 'allow' } ] } ];
256   my $cwd = $options->{cwd};
257   my $file = "$cwd/logs/${name}_noit.conf";
258   open (my $o, ">$file") || BAIL_OUT("can't write config: $file");
259   print $o qq{<?xml version="1.0" encoding="utf8" standalone="yes"?>\n};
260   print $o qq{<noit>};
261   make_eventer_config($o, $options);
262   make_rest_acls($o, $options);
263   make_logs_config($o, $options);
264   make_modules_config($o, $options);
265   make_noit_listeners_config($o, $options);
266   make_checks_config($o, $options);
267   make_filtersets_config($o, $options);
268   print $o qq{</noit>\n};
269   close($o);
270   return $file;
271 }
272
273 sub make_stratcon_noits_config {
274   my ($o, $opts) = @_;
275   my $cwd = $opts->{cwd};
276   $opts->{noit_api_port} ||= $NOIT_API_PORT;
277   print $o qq{
278   <noits>
279     <sslconfig>
280       <certificate_file>$cwd/../test-stratcon.crt</certificate_file>
281       <key_file>$cwd/../test-stratcon.key</key_file>
282       <ca_chain>$cwd/../test-ca.crt</ca_chain>
283     </sslconfig>
284     <config>
285       <reconnect_initial_interval>1000</reconnect_initial_interval>
286       <reconnect_maximum_interval>15000</reconnect_maximum_interval>
287     </config>
288 };
289   foreach my $n (@{$opts->{noits}}) {
290     print $o qq{    <noit};
291     while (my ($k,$v) = each %$n) {
292       print $o qq{ $k=\"$v\"};
293     }
294     print $o qq{/>\n};
295   }
296   print $o qq{</noits>\n};
297 }
298
299 sub make_stratcon_listeners_config {
300   my ($o, $opts) = @_;
301   my $cwd = $opts->{cwd};
302   $opts->{stratcon_api_port} ||= $STRATCON_API_PORT;
303   $opts->{stratcon_web_port} ||= $STRATCON_WEB_PORT;
304   print $o qq{
305   <listeners>
306     <sslconfig>
307       <certificate_file>$cwd/../test-stratcon.crt</certificate_file>
308       <key_file>$cwd/../test-stratcon.key</key_file>
309       <ca_chain>$cwd/../test-ca.crt</ca_chain>
310     </sslconfig>
311     <realtime type="http_rest_api">
312       <listener address="*" port="$opts->{stratcon_web_port}">
313         <config>
314           <hostname>stratcon.noit.example.com</hostname>
315           <document_domain>noit.example.com</document_domain>
316         </config>
317       </listener>
318     </realtime>
319     <listener type="control_dispatch" address="*" port="$opts->{stratcon_api_port}" ssl="on" />
320   </listeners>
321 };
322 }
323
324 sub make_iep_config {
325   my ($o, $opts) = @_;
326   my $cwd = $opts->{cwd};
327   $opts->{iep}->{disabled} ||= 'false';
328   mkdir("$cwd/logs/$opts->{name}_iep_root");
329   open(my $run, "<$cwd/../../src/java/run-iep.sh") ||
330     BAIL_OUT("cannot open source run-iep.sh");
331   sysopen(my $newrun, "$cwd/logs/$opts->{name}_iep_root/run-iep.sh", O_WRONLY|O_CREAT, 0755) ||
332     BAIL_OUT("cannot open target run-iep.sh");
333   while(<$run>) {
334     s%^DIRS="%DIRS="$cwd/../../src/java $cwd/../../src/java/lib %;
335     print $newrun $_;
336   }
337   close($run);
338   close($newrun);
339   print $o qq{
340   <iep disabled="$opts->{iep}->{disabled}">
341     <start directory="$cwd/logs/$opts->{name}_iep_root"
342            command="$cwd/logs/$opts->{name}_iep_root/run-iep.sh" />
343 };
344   foreach my $mqt (keys %{$opts->{iep}->{mq}}) {
345     print $o qq{    <mq type="$mqt">\n};
346     while (my ($k,$v) = each %{$opts->{iep}->{mq}->{mqt}}) {
347       print $o qq{      <$k>$v</$k>\n};
348     }
349     print $o qq{    </mq>\n};
350   }
351   foreach my $bt (keys %{$opts->{iep}->{broker}}) {
352     print $o qq{    <broker adapter="$bt">\n};
353     while (my ($k,$v) = each %{$opts->{iep}->{broker}->{bt}}) {
354       print $o qq{      <$k>$v</$k>\n};
355     }
356     print $o qq{    </broker>\n};
357   }
358   print $o qq{</iep>\n};
359 }
360 sub make_database_config {
361   my ($o, $opts) = @_;
362   my $cwd = $opts->{cwd};
363   print $o qq{
364   <database>
365     <journal>
366       <path>$cwd/logs/$opts->{name}_stratcon.persist</path>
367     </journal>
368     <dbconfig>
369       <host>localhost</host>
370       <port>$NOIT_TEST_DB_PORT</port>
371       <dbname>reconnoiter</dbname>
372       <user>stratcon</user>
373       <password>stratcon</password>
374     </dbconfig>
375     <statements>
376       <allchecks><![CDATA[
377         SELECT remote_address, id, target, module, name
378           FROM check_currently
379       ]]></allchecks>
380       <findcheck><![CDATA[
381         SELECT remote_address, id, target, module, name
382           FROM check_currently
383          WHERE sid = \$1
384       ]]></findcheck>
385       <allstoragenodes><![CDATA[
386         SELECT storage_node_id, fqdn, dsn
387           FROM stratcon.storage_node
388       ]]></allstoragenodes>
389       <findstoragenode><![CDATA[
390         SELECT fqdn, dsn
391           FROM stratcon.storage_node
392          WHERE storage_node_id = \$1
393       ]]></findstoragenode>
394       <mapallchecks><![CDATA[
395         SELECT id, sid, noit as remote_cn, storage_node_id, fqdn, dsn
396           FROM stratcon.map_uuid_to_sid LEFT JOIN stratcon.storage_node USING (storage_node_id)
397       ]]></mapallchecks>
398       <mapchecktostoragenode><![CDATA[
399         SELECT o_storage_node_id as storage_node_id, o_sid as sid,
400                o_fqdn as fqdn, o_dsn as dsn
401           FROM stratcon.map_uuid_to_sid(\$1,\$2)
402       ]]></mapchecktostoragenode>
403       <check><![CDATA[
404         INSERT INTO check_archive_%Y%m%d
405                     (remote_address, whence, sid, id, target, module, name)
406              VALUES (\$1, 'epoch'::timestamptz + (\$2 || ' seconds')::interval,
407                      \$3, \$4, \$5, \$6, \$7)
408       ]]></check>
409       <status><![CDATA[
410         INSERT INTO check_status_archive_%Y%m%d
411                     (whence, sid, state, availability, duration, status)
412              VALUES ('epoch'::timestamptz + (\$1 || ' seconds')::interval,
413                      \$2, \$3, \$4, \$5, \$6)
414       ]]></status>
415       <metric_numeric><![CDATA[
416         INSERT INTO metric_numeric_archive_%Y%m%d
417                     (whence, sid, name, value)
418              VALUES ('epoch'::timestamptz + (\$1 || ' seconds')::interval,
419                      \$2, \$3, \$4)
420       ]]></metric_numeric>
421       <metric_text><![CDATA[
422         INSERT INTO metric_text_archive_%Y%m%d
423                     ( whence, sid, name,value)
424              VALUES ('epoch'::timestamptz + (\$1 || ' seconds')::interval,
425                      \$2, \$3, \$4)
426       ]]></metric_text>
427       <config><![CDATA[
428         SELECT stratcon.update_config
429                (\$1, \$2, \$3,
430                 'epoch'::timestamptz + (\$4 || ' seconds')::interval,
431                 \$5)
432       ]]></config>
433       <findconfig><![CDATA[
434         SELECT config FROM stratcon.current_node_config WHERE remote_cn = \$1
435       ]]></findconfig>
436     </statements>
437   </database>
438 };
439 }
440
441 sub make_stratcon_config {
442   my $name = shift;
443   my $options = shift;
444   $options->{cwd} ||= cwd();
445   $options->{generics} ||= { 'stomp_driver' => { image => 'stomp_driver' } };
446   $options->{rest_acls} ||= [ { type => 'deny', rules => [ { type => 'allow' } ] } ];
447   $options->{iep}->{mq} ||= { 'stomp' => {} };
448   my $cwd = $options->{cwd};
449   my $file = "$cwd/logs/${name}_stratcon.conf";
450   open (my $o, ">$file") || BAIL_OUT("can't write config: $file");
451   print $o qq{<?xml version="1.0" encoding="utf8" standalone="yes"?>\n};
452   print $o qq{<stratcon>};
453   make_eventer_config($o, $options);
454   make_rest_acls($o, $options);
455   make_stratcon_noits_config($o, $options);
456   make_logs_config($o, $options);
457   make_modules_config($o, $options);
458   make_stratcon_listeners_config($o, $options);
459   make_database_config($o, $options);
460   make_iep_config($o, $options);
461   print $o qq{</stratcon>\n};
462   close($o);
463   return $file;
464 }
465
466 sub start_noit {
467   my $name = shift;
468   my $options = shift;
469   $options->{name} = $name;
470   return 0 if $noit_pid;
471   my $conf = make_noit_config($name, $options);
472   $noit_pid = fork();
473   mkdir "logs";
474   if($noit_pid == 0) {
475     close(STDIN);
476     open(STDIN, "</dev/null");
477     close(STDOUT);
478     open(STDOUT, ">/dev/null");
479     close(STDERR);
480     open(STDERR, ">logs/${name}_noit.log");
481     my @args = ( 'noitd', '-D', '-c', $conf );
482     exec { '../../src/noitd' } @args;
483     exit(-1);
484   }
485   return $noit_pid;
486 }
487 sub stop_noit {
488   kill 9, $noit_pid if($noit_pid && kill 1, $noit_pid);
489   $noit_pid = 0;
490   return 1;
491 }
492
493 sub start_stratcon {
494   my $name = shift;
495   my $options = shift;
496   $options->{name} = $name;
497   return 0 if $stratcon_pid;
498   my $conf = make_stratcon_config($name, $options);
499   $stratcon_pid = fork();
500   mkdir "logs";
501   if($stratcon_pid == 0) {
502     close(STDIN);
503     open(STDIN, "</dev/null");
504     close(STDOUT);
505     open(STDOUT, ">/dev/null");
506     close(STDERR);
507     open(STDERR, ">logs/${name}_stratcon.log");
508     my @args = ( 'stratcond', '-D', '-c', $conf );
509     exec { '../../src/stratcond' } @args;
510     exit(-1);
511   }
512   return $stratcon_pid;
513 }
514 sub stop_stratcon {
515   kill 9, $stratcon_pid if($stratcon_pid && kill 1, $stratcon_pid);
516   $stratcon_pid = 0;
517   return 1;
518 }
519
520 END {
521   kill 9, $noit_pid if($noit_pid && kill 1, $noit_pid);
522   kill 9, $stratcon_pid if($stratcon_pid && kill 1, $stratcon_pid);
523 }
524 1;
Note: See TracBrowser for help on using the browser.