root/test/t/testconfig.pm

Revision 239594a76cc5a52d016357dde39705aee39bd2e4, 17.3 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

fix this to run on my Mac again

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