package App::Netdisco::Configuration; use App::Netdisco::Environment; use Dancer ':script'; use Path::Class 'dir'; BEGIN { if (setting('include_paths') and ref [] eq ref setting('include_paths')) { # stuff useful locations into @INC push @{setting('include_paths')}, dir(($ENV{NETDISCO_HOME} || $ENV{HOME}), 'nd-site-local', 'lib')->stringify if (setting('site_local_files')); unshift @INC, @{setting('include_paths')}; } } # set up database schema config from simple config vars if (ref {} eq ref setting('database')) { my $name = ($ENV{NETDISCO_DBNAME} || setting('database')->{name} || 'netdisco'); my $host = setting('database')->{host}; my $user = setting('database')->{user}; my $pass = setting('database')->{pass}; my $dsn = "dbi:Pg:dbname=${name}"; $dsn .= ";host=${host}" if $host; # set up the netdisco schema now we have access to the config # but only if it doesn't exist from an earlier config style setting('plugins')->{DBIC}->{netdisco} ||= { dsn => $dsn, user => $user, password => $pass, options => { AutoCommit => 1, RaiseError => 1, auto_savepoint => 1, pg_enable_utf8 => 1, }, schema_class => 'App::Netdisco::DB', }; foreach my $c (@{setting('external_databases')}) { my $schema = delete $c->{tag} or next; next if $schema eq 'netdisco'; setting('plugins')->{DBIC}->{$schema} = $c; setting('plugins')->{DBIC}->{$schema}->{schema_class} ||= 'App::Netdisco::GenericDB'; } } # always set this $ENV{DBIC_TRACE_PROFILE} = 'console'; # if snmp_auth or device_auth not set, add defaults to community{_rw} if ((setting('snmp_auth') and 0 == scalar @{ setting('snmp_auth') }) or (setting('device_auth') and 0 == scalar @{ setting('device_auth') })) { config->{'community'} = [ @{setting('community')}, 'public' ]; config->{'community_rw'} = [ @{setting('community_rw')}, 'private' ]; } # defaults for workers setting('workers')->{queue} ||= 'PostgreSQL'; if (exists setting('workers')->{interactives} or exists setting('workers')->{pollers}) { setting('workers')->{tasks} = (setting('workers')->{pollers} || 0) + (setting('workers')->{interactives} || 0); delete setting('workers')->{pollers}; delete setting('workers')->{interactives}; } # force skipped DNS resolution, if unset setting('dns')->{hosts_file} ||= '/etc/hosts'; setting('dns')->{no} ||= ['fe80::/64','169.254.0.0/16']; # set max outstanding requests for AnyEvent::DNS $ENV{'PERL_ANYEVENT_MAX_OUTSTANDING_DNS'} = setting('dns')->{max_outstanding} || 50; $ENV{'PERL_ANYEVENT_HOSTS'} = setting('dns')->{hosts_file}; # load /etc/hosts setting('dns')->{'ETCHOSTS'} = {}; { # AE::DNS::EtcHosts only works for A/AAAA/SRV, but we want PTR. # this loads+parses /etc/hosts file using AE. dirty hack. use AnyEvent::Socket 'format_address'; use AnyEvent::DNS::EtcHosts; AnyEvent::DNS::EtcHosts::_load_hosts_unless(sub{},AE::cv); no AnyEvent::DNS::EtcHosts; # unimport setting('dns')->{'ETCHOSTS'}->{$_} = [ map { [ $_ ? (format_address $_->[0]) : '' ] } @{ $AnyEvent::DNS::EtcHosts::HOSTS{ $_ } } ] for keys %AnyEvent::DNS::EtcHosts::HOSTS; } # support unordered dictionary as if it were a single item list if (ref {} eq ref setting('device_identity')) { config->{'device_identity'} = [ setting('device_identity') ]; } else { config->{'device_identity'} ||= [] } # copy devices_no and devices_only into others foreach my $name (qw/devices_no devices_only discover_no macsuck_no arpnip_no nbtstat_no discover_only macsuck_only arpnip_only nbtstat_only/) { config->{$name} ||= []; config->{$name} = [setting($name)] if ref [] ne ref setting($name); } foreach my $name (qw/discover_no macsuck_no arpnip_no nbtstat_no/) { push @{setting($name)}, @{ setting('devices_no') }; } foreach my $name (qw/discover_only macsuck_only arpnip_only nbtstat_only/) { push @{setting($name)}, @{ setting('devices_only') }; } # legacy config item names config->{'devport_vlan_limit'} = config->{'deviceport_vlan_membership_threshold'} if setting('deviceport_vlan_membership_threshold') and not setting('devport_vlan_limit'); delete config->{'deviceport_vlan_membership_threshold'}; config->{'schedule'} = config->{'housekeeping'} if setting('housekeeping') and not setting('schedule'); delete config->{'housekeeping'}; # schedule expire used to be called expiry setting('schedule')->{expire} ||= setting('schedule')->{expiry} if setting('schedule') and exists setting('schedule')->{expiry}; delete config->{'schedule'}->{'expiry'} if setting('schedule'); # upgrade reports config from hash to list if (setting('reports') and ref {} eq ref setting('reports')) { config->{'reports'} = [ map {{ tag => $_, %{ setting('reports')->{$_} } }} keys %{ setting('reports') } ]; } true;