root/test/t/testconfig.pm

Revision 38385c3025d5f1da24a7b98dfa70f410e42e7fb0, 15.9 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

cleaner error detection

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