root/test/t/testconfig.pm

Revision 3739c78a534317b34706e055d7a120bdd59ab883, 15.7 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 4 years ago)

fixes #245

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