#!/usr/bin/perl -w #use strict; use warnings; use Config::General qw(ParseConfig SaveConfig); use Sys::Hostname; use English qw( -no_match_vars ); use Module::Load; use File::Temp qw(tempfile); =head1 NAME psConfigureDaemon - Ask a series of questions to generate a configuration file. =head1 DESCRIPTION Ask questions based on a service to generate a configuration file. =cut my $was_installed = 0; my $DEFAULT_FILE; my $confdir; if ($was_installed) { $confdir = "XXX_CONFDIR_XXX"; } else { $confdir = "." } $DEFAULT_FILE = $confdir . "/daemon.conf"; print " -- perfSONAR-PS Daemon Configuration --\n"; print " - [press enter for the default choice] -\n\n"; my $file = shift; if ( not $file ) { $file = &ask( "What file should I write the configuration to? ", $DEFAULT_FILE, undef, '.+' ); } my $tmp; my $default_hostname = hostname(); my $hostname; my %config = (); if ( -f $file ) { %config = ParseConfig($file); } # make sure all the endpoints start with a "/". if ( defined $config{"port"} ) { foreach my $port ( keys %{ $config{"port"} } ) { if ( defined $config{"port"}->{$port}->{"endpoint"} ) { foreach my $endpoint ( keys %{ $config{"port"}->{$port}->{"endpoint"} } ) { my $new_endpoint = $endpoint; if ( $endpoint =~ /^[^\/]/mx ) { $new_endpoint = "/" . $endpoint; } if ( $endpoint ne $new_endpoint ) { $config{"port"}->{$port}->{"endpoint"}->{$new_endpoint} = $config{"port"}->{$port}->{"endpoint"}->{$endpoint}; delete( $config{"port"}->{$port}->{"endpoint"}->{$endpoint} ); } } } } } while (1) { my $input; print "1) Add/Edit endpoint\n"; print "2) Enable/Disable port/endpoint\n"; print "3) Set global values\n"; print "4) Save configuration\n"; print "5) Exit\n"; $input = &ask( "? ", q{}, undef, '[12345]' ); if ( $input == 5 ) { exit(0); } elsif ( $input == 4 ) { if ( -f $file ) { system("mv $file $file~"); } SaveConfig_mine( $file, \%config ); print "\n"; print "Saved config to $file\n"; print "\n"; } elsif ( $input == 3 ) { $config{"max_worker_processes"} = &ask( "Enter the maximum number of children processes (0 means infinite) ", "0", $config{"max_worker_processes"}, '^\d+$' ); $config{"max_worker_lifetime"} = &ask( "Enter number of seconds a child can process before it is stopped (0 means infinite) ", "0", $config{"max_worker_lifetime"}, '^\d+$' ); $config{"disable_echo"} = &ask( "Disable echo by default (0 for yes, 1 for now) ", 0, $config{"disable_echo"}, '^[01]$' ); $config{"ls_instance"} = &ask( "The LS for MAs to register with ", "http://packrat.internet2.edu:8005/perfSONAR_PS/services/LS", $config{"ls_instance"}, '(^http|^$)' ); $config{"ls_registration_interval"} = &ask( "Interval between when LS registrations occur [in minutes] ", 60, $config{"ls_registration_interval"}, '^\d+$' ); $config{"reaper_interval"} = &ask( "Interval between when children are repeaed [in seconds] ", 20, $config{"reaper_interval"}, '^\d+$' ); $config{"pid_dir"} = &ask( "Enter pid dir location ", "/var/run", $config{"pid_dir"}, q{} ); $config{"pid_file"} = &ask( "Enter pid filename ", "ps.pid", $config{"pid_file"}, q{} ); } elsif ( $input == 2 ) { my @elements = (); my %status = (); foreach my $port ( sort keys %{ $config{"port"} } ) { next if ( !defined $config{"port"}->{$port}->{"endpoint"} ); push @elements, $port; if ( defined $config{"port"}->{$port}->{"disabled"} and $config{"port"}->{$port}->{"disabled"} == 1 ) { $status{$port} = 1; } } foreach my $port ( sort keys %{ $config{"port"} } ) { next if ( !defined $config{"port"}->{$port}->{"endpoint"} ); foreach my $endpoint ( sort keys %{ $config{"port"}->{$port}->{"endpoint"} } ) { push @elements, "$port$endpoint"; if ( defined $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"disabled"} and $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"disabled"} == 1 ) { $status{"$port$endpoint"} = 1; } } } if ( $#elements > -1 ) { print "\n"; print "Select element to enable/disable: \n"; my $len = $#elements; for my $i ( 0 .. $len ) { print " $i) $elements[$i] "; print " *" if ( defined $status{ $elements[$i] } ); print "\n"; } print "\n"; print " * element is disabled\n"; print "\n"; do { $input = &ask( "Select a number from the above ", q{}, undef, '^\d+$' ); } while ( $input > $#elements ); my $new_status; if ( defined $status{ $elements[$input] } ) { $new_status = 0; } else { $new_status = 1; } print "\n"; if ($new_status) { print "Disabling"; } else { print "Enabling"; } if ( $elements[$input] =~ /^(\d+)(\/.*)$/mx ) { print " endpoint " . $elements[$input] . "\n"; $config{"port"}->{$1}->{"endpoint"}->{$2}->{"disabled"} = $new_status; } elsif ( $elements[$input] =~ /^(\d+)$/mx ) { print " port " . $elements[$input] . "\n"; $config{"port"}->{$1}->{"disabled"} = $new_status; } print "\n"; } } elsif ( $input == 1 ) { my @endpoints = (); foreach my $port ( sort keys %{ $config{"port"} } ) { next if ( !defined $config{"port"}->{$port}->{"endpoint"} ); foreach my $endpoint ( sort keys %{ $config{"port"}->{$port}->{"endpoint"} } ) { push @endpoints, "$port$endpoint"; } } if ( $#endpoints > -1 ) { print "\n"; print "Existing Endpoints: \n"; my $len = $#endpoints; for my $i ( 0 .. $len ) { print " $i) $endpoints[$i]\n"; } print "\n"; } do { $input = &ask( "Enter endpoint in form 'port/endpoint_path' (e.g. 8080/perfSONAR_PS/services/SERVICE_NAME) or select from a number from the above ", q{}, undef, '^(\d+[\/].*|\d+)$' ); if ( $input =~ /^\d+$/mx ) { $input = $endpoints[$input]; } } while ( !( $input =~ /\d+[\/].*/mx ) ); my ( $port, $endpoint ); if ( $input =~ /(\d+)([\/].*)/mx ) { $port = $1; $endpoint = $2; } if ( !defined $config{"port"} ) { my %hash = (); $config{"port"} = \%hash; } if ( !defined $config{"port"}->{$port} ) { my %hash = (); $config{"port"}->{$port} = \%hash; $config{"port"}->{$port}->{"endpoint"} = (); } if ( !defined $config{"port"}->{$port}->{"endpoint"}->{$endpoint} ) { $config{"port"}->{$port}->{"endpoint"}->{$endpoint} = (); } my $valid_module = 0; my $module = $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"module"}; if ( defined $module ) { if ( $module eq "perfSONAR_PS::Services::MA::SNMP" ) { $module = "snmp"; } elsif ( $module eq "perfSONAR_PS::Services::MA::Status" ) { $module = "status"; } elsif ( $module eq "perfSONAR_PS::Services::MA::CircuitStatus" ) { $module = "circuitstatus"; } elsif ( $module eq "perfSONAR_PS::Services::MA::Topology" ) { $module = "topology"; } elsif ( $module eq "perfSONAR_PS::Services::LS::LS" ) { $module = "ls"; } elsif ( $module eq "perfSONAR_PS::Services::MA::perfSONARBOUY" ) { $module = "perfsonarbouy"; } } my %opts; do { $module = &ask( "Enter endpoint module [snmp,ls,status,circuitstatus,topology,perfsonarbouy] ", q{}, $module, q{} ); $module = lc($module); if ( $module eq "snmp" or $module eq "status" or $module eq "ls" or $module eq "circuitstatus" or $module eq "topology" or $module eq "perfsonarbouy" ) { $valid_module = 1; } } while ( $valid_module == 0 ); if ( !defined $hostname ) { $hostname = &ask( "Enter the external host or IP for this machine ", $hostname, $default_hostname, '.+' ); } my $accesspoint = &ask( "Enter the accesspoint for this service ", "http://$hostname:$port$endpoint", undef, '^http' ); if ( $module eq "snmp" ) { $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"module"} = "perfSONAR_PS::Services::MA::SNMP"; config_snmp_ma( $config{"port"}->{$port}->{"endpoint"}->{$endpoint}, $accesspoint, \%config ); } elsif ( $module eq "status" ) { $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"module"} = "perfSONAR_PS::Services::MA::Status"; config_status_ma( $config{"port"}->{$port}->{"endpoint"}->{$endpoint}, $accesspoint, \%config ); } elsif ( $module eq "circuitstatus" ) { $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"module"} = "perfSONAR_PS::Services::MA::CircuitStatus"; config_circuitstatus_ma( $config{"port"}->{$port}->{"endpoint"}->{$endpoint}, $accesspoint, \%config ); } elsif ( $module eq "topology" ) { $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"module"} = "perfSONAR_PS::Services::MA::Topology"; config_topology_ma( $config{"port"}->{$port}->{"endpoint"}->{$endpoint}, $accesspoint, \%config ); } elsif ( $module eq "ls" ) { $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"module"} = "perfSONAR_PS::Services::LS::LS"; config_ls( $config{"port"}->{$port}->{"endpoint"}->{$endpoint}, $accesspoint, \%config ); } elsif ( $module eq "perfsonarbouy" ) { $config{"port"}->{$port}->{"endpoint"}->{$endpoint}->{"module"} = "perfSONAR_PS::Services::MA::perfSONARBOUY"; config_perfsonarbouy_ma( $config{"port"}->{$port}->{"endpoint"}->{$endpoint}, $accesspoint, \%config ); } } } sub config_ls { my ( $config, $accesspoint, $def_config ) = @_; if ( !defined $config->{"ls"} ) { $config->{"ls"} = (); } $config->{"ls"}->{"ls_ttl"} = &ask( "Enter default TTL for registered data [in minutes] ", "60", $config->{"ls"}->{"ls_ttl"}, '\d+' ); $config->{"ls"}->{"metadata_db_name"} = &ask( "Enter the directory of the XML database ", $confdir . "/xmldb", $config->{"ls"}->{"metadata_db_name"}, '^\/' ); $config->{"ls"}->{"metadata_db_file"} = &ask( "Enter the name of the container inside of the XML database ", "store.dbxml", $config->{"ls"}->{"metadata_db_file"}, '.+' ); $config->{"ls"}->{"reaper_interval"} = &ask( "Should the LS periodically remove old registration information (0 for no, 1 for yes) ", "0", $config->{"ls"}->{"reaper_interval"}, '^[01]$' ); if ( $config->{"ls"}->{"reaper_interval"} ) { $config->{"ls"}->{"reaper_interval"} = &ask( "Enter the time between LS removal [in minutes] ", "30", "30", '^\d+$' ); } $config->{"ls"}->{"service_name"} = &ask( "Enter a name for this service ", "Lookup Service", $config->{"ls"}->{"service_name"}, '.+' ); $config->{"ls"}->{"service_type"} = &ask( "Enter the service type ", "MA", $config->{"ls"}->{"service_type"}, '.+' ); $config->{"ls"}->{"service_description"} = &ask( "Enter a service description ", "Lookup Service", $config->{"ls"}->{"service_description"}, '.+' ); $config->{"ls"}->{"service_accesspoint"} = &ask( "Enter the service's URI ", $accesspoint, $config->{"ls"}->{"service_accesspoint"}, '^http:\/\/' ); return; } sub config_perfsonarbouy_ma { my ( $config, $accesspoint, $def_config ) = @_; my $amiconfdir = $confdir; $config->{"perfsonarbouy"}->{"owmesh"} = &ask( "Enter the directory *LOCATION* of the 'owmesh.conf' file: ", $amiconfdir, $config->{"perfsonarbouy"}->{"owmesh"}, '.+' ); $amiconfdir = $config->{"perfsonarbouy"}->{"owmesh"}; $config->{"perfsonarbouy"}->{"metadata_db_type"} = &ask( "Enter the database type to read from (file or xmldb) ", "file", $config->{"perfsonarbouy"}->{"metadata_db_type"}, '(file|xmldb)' ); if ( $config->{"perfsonarbouy"}->{"metadata_db_type"} eq "file" ) { delete $config->{"perfsonarbouy"}->{"metadata_db_file"} if $config->{"perfsonarbouy"}->{"metadata_db_file"} and $config->{"perfsonarbouy"}->{"metadata_db_file"} =~ m/dbxml$/mx; $config->{"perfsonarbouy"}->{"metadata_db_file"} = &ask( "Enter the filename of the XML file ", $amiconfdir . "/store.xml", $config->{"perfsonarbouy"}->{"metadata_db_file"}, '\.xml$' ); } elsif ( $config->{"perfsonarbouy"}->{"metadata_db_type"} eq "xmldb" ) { $config->{"perfsonarbouy"}->{"metadata_db_name"} = &ask( "Enter the directory of the XML database ", $amiconfdir . "/xmldb", $config->{"perfsonarbouy"}->{"metadata_db_name"}, '.+' ); delete $config->{"perfsonarbouy"}->{"metadata_db_file"} if $config->{"perfsonarbouy"}->{"metadata_db_file"} and $config->{"perfsonarbouy"}->{"metadata_db_file"} =~ m/\.xml$/mx; $config->{"perfsonarbouy"}->{"metadata_db_file"} = &ask( "Enter the name of the container inside of the XML database ", "store.dbxml", $config->{"perfsonarbouy"}->{"metadata_db_file"}, '.+' ); } $config->{"perfsonarbouy"}->{"enable_registration"} = &ask( "Will this service register with an LS (0 for no, 1 for yes)", "0", $config->{"perfsonarbouy"}->{"enable_registration"}, '^[01]$' ); if ( $config->{"perfsonarbouy"}->{"enable_registration"} eq "1" ) { my $registration_interval = $def_config->{"ls_registration_interval"}; $registration_interval = $config->{"perfsonarbouy"}->{"ls_registration_interval"} if ( defined $config->{"perfsonarbouy"}->{"ls_registration_interval"} ); $config->{"perfsonarbouy"}->{"ls_registration_interval"} = &ask( "Interval between when LS registrations occur [in minutes] ", "30", $registration_interval, '^\d+$' ); my $ls_instance = $def_config->{"ls_instance"}; $ls_instance = $config->{"perfsonarbouy"}->{"ls_instance"} if ( defined $config->{"perfsonarbouy"}->{"ls_instance"} ); $config->{"perfsonarbouy"}->{"ls_instance"} = &ask( "URL of an LS to register with ", q{}, $ls_instance, '^http:\/\/' ); } $config->{"perfsonarbouy"}->{"service_name"} = &ask( "Enter a name for this service ", "perfSONARBOUY MA", $config->{"perfsonarbouy"}->{"service_name"}, '.+' ); $config->{"perfsonarbouy"}->{"service_type"} = &ask( "Enter the service type ", "MA", $config->{"perfsonarbouy"}->{"service_type"}, '.+' ); $config->{"perfsonarbouy"}->{"service_description"} = &ask( "Enter a service description ", "perfSONARBOUY MA", $config->{"perfsonarbouy"}->{"service_description"}, '.+' ); $config->{"perfsonarbouy"}->{"service_accesspoint"} = &ask( "Enter the service's URI ", $accesspoint, $config->{"perfsonarbouy"}->{"service_accesspoint"}, '^http:\/\/' ); return; } sub config_snmp_ma { my ( $config, $accesspoint, $def_config ) = @_; my $rrdtool = q{}; if ( open( RRDTOOL, "which rrdtool |" ) ) { $rrdtool = ; $rrdtool =~ s/rrdtool:\s+//mx; $rrdtool =~ s/\n//gmx; unless ( close(RRDTOOL) ) { return -1; } } unless ($rrdtool) { return -1; } $config->{"snmp"}->{"rrdtool"} = &ask( "Enter the location of the RRD binary ", $rrdtool, $config->{"snmp"}->{"rrdtool"}, '.+' ); $config->{"snmp"}->{"default_resolution"} = &ask( "Enter the default resolution of RRD queries ", "300", $config->{"snmp"}->{"default_resolution"}, '^\d+$' ); $config->{"snmp"}->{"metadata_db_type"} = &ask( "Enter the database type to read from (file or xmldb) ", "file", $config->{"snmp"}->{"metadata_db_type"}, '(file|xmldb)' ); my $makeStore = &ask( "Automatically generate a 'test' metadata database (0 for no, 1 for yes) ", "0", "0", '^[01]$' ); if ( $makeStore ) { eval { # load RRDp; use RRDp; $RRDp::error_mode = 'catch'; RRDp::start $config->{"snmp"}->{"rrdtool"}; my $cmd .= "create ".$confdir."/localhost.rrd --start N --step 1 "; $cmd .= "DS:ifinoctets:COUNTER:10:U:U "; $cmd .= "DS:ifoutoctets:COUNTER:10:U:U "; $cmd .= "DS:ifinerrors:COUNTER:10:U:U "; $cmd .= "DS:ifouterrors:COUNTER:10:U:U "; $cmd .= "DS:ifindiscards:COUNTER:10:U:U "; $cmd .= "DS:ifoutdiscards:COUNTER:10:U:U "; $cmd .= "RRA:AVERAGE:0.5:1:241920 "; $cmd .= "RRA:AVERAGE:0.5:2:120960 "; $cmd .= "RRA:AVERAGE:0.5:6:40320 "; $cmd .= "RRA:AVERAGE:0.5:12:20160 "; $cmd .= "RRA:AVERAGE:0.5:24:10080 "; $cmd .= "RRA:AVERAGE:0.5:36:6720 "; $cmd .= "RRA:AVERAGE:0.5:48:5040 "; $cmd .= "RRA:AVERAGE:0.5:60:4032 "; $cmd .= "RRA:AVERAGE:0.5:120:2016"; RRDp::cmd $cmd; my $answer = RRDp::read; }; if ($EVAL_ERROR) { return -1; } my($fileHandle, $fileName) = tempfile(); $makeStore = $fileName; print $fileHandle "\n"; print $fileHandle "\n\n"; foreach my $et (("netutil", "neterr", "netdisc")) { foreach my $dir (("in", "out")) { print $fileHandle " \n"; if($et eq "netutil") { print $fileHandle " \n"; } elsif($et eq "neterr") { print $fileHandle " \n"; } elsif($et eq "netdisc") { print $fileHandle " \n"; } print $fileHandle " \n"; print $fileHandle " 127.0.0.1\n"; print $fileHandle " localhost\n"; print $fileHandle " eth0\n"; print $fileHandle " 2\n"; print $fileHandle " ".$dir."\n"; print $fileHandle " 1000000000\n"; print $fileHandle " \n"; if($et eq "netutil") { print $fileHandle " \n"; print $fileHandle " http://ggf.org/ns/nmwg/characteristic/utilization/2.0\n"; } elsif($et eq "neterr") { print $fileHandle " \n"; print $fileHandle " http://ggf.org/ns/nmwg/characteristic/errors/2.0\n"; } elsif($et eq "netdisc") { print $fileHandle " \n"; print $fileHandle " http://ggf.org/ns/nmwg/characteristic/discards/2.0\n"; } print $fileHandle " http://ggf.org/ns/nmwg/tools/snmp/2.0\n"; print $fileHandle " \n\n"; print $fileHandle " \n"; print $fileHandle " \n"; print $fileHandle " \n"; print $fileHandle " http://ggf.org/ns/nmwg/tools/snmp/2.0\n"; if($et eq "netutil") { print $fileHandle " http://ggf.org/ns/nmwg/characteristic/utilization/2.0\n"; } elsif($et eq "neterr") { print $fileHandle " http://ggf.org/ns/nmwg/characteristic/errors/2.0\n"; } elsif($et eq "netdisc") { print $fileHandle " http://ggf.org/ns/nmwg/characteristic/discards/2.0\n"; } print $fileHandle " rrd\n"; print $fileHandle " ".$confdir."/localhost.rrd\n"; if($et eq "netutil") { print $fileHandle " Bps\n"; print $fileHandle " if".$dir."octets\n"; } elsif($et eq "neterr") { print $fileHandle " Eps\n"; print $fileHandle " if".$dir."errors\n"; } elsif($et eq "netdisc") { print $fileHandle " Dps\n"; print $fileHandle " if".$dir."discards\n"; } print $fileHandle " \n"; print $fileHandle " \n"; print $fileHandle " \n\n"; } } print $fileHandle "\n"; close($fileHandle); } if ( $config->{"snmp"}->{"metadata_db_type"} eq "file" ) { delete $config->{"snmp"}->{"metadata_db_file"} if $config->{"snmp"}->{"metadata_db_file"} and $config->{"snmp"}->{"metadata_db_file"} =~ m/dbxml$/mx; $config->{"snmp"}->{"metadata_db_file"} = &ask( "Enter the filename of the XML file ", $confdir . "/store.xml", $config->{"snmp"}->{"metadata_db_file"}, '\.xml$' ); if ( $makeStore ) { if ( -f $config->{"snmp"}->{"metadata_db_file"} ) { system("mv " . $config->{"snmp"}->{"metadata_db_file"} . " " . $config->{"snmp"}->{"metadata_db_file"} . "~"); } system( "mv " . $makeStore . " " . $config->{"snmp"}->{"metadata_db_file"}); } delete $config->{"snmp"}->{"db_autoload"} if $config->{"snmp"}->{"db_autoload"}; delete $config->{"snmp"}->{"autoload_metadata_db_file"} if $config->{"snmp"}->{"autoload_metadata_db_file"}; delete $config->{"snmp"}->{"metadata_db_name"} if $config->{"snmp"}->{"metadata_db_name"}; } elsif ( $config->{"snmp"}->{"metadata_db_type"} eq "xmldb" ) { $config->{"snmp"}->{"metadata_db_name"} = &ask( "Enter the directory of the XML database ", $confdir . "/xmldb", $config->{"snmp"}->{"metadata_db_name"}, '.+' ); delete $config->{"snmp"}->{"metadata_db_file"} if $config->{"snmp"}->{"metadata_db_file"} and $config->{"snmp"}->{"metadata_db_file"} =~ m/\.xml$/mx; $config->{"snmp"}->{"metadata_db_file"} = &ask( "Enter the name of the container inside of the XML database ", "store.dbxml", $config->{"snmp"}->{"metadata_db_file"}, '.+' ); if ( $makeStore ) { $config->{"snmp"}->{"db_autoload"} = 1; $config->{"snmp"}->{"autoload_metadata_db_file"} = &ask( "Enter the filename of the base XML file to load ", $confdir . "/store.xml", $config->{"snmp"}->{"autoload_metadata_db_file"}, '\.xml$' ); if ( -f $config->{"snmp"}->{"autoload_metadata_db_file"} ) { system("mv " . $config->{"snmp"}->{"autoload_metadata_db_file"} . " " . $config->{"snmp"}->{"autoload_metadata_db_file"} . "~"); } system( "mv " . $makeStore . " " . $config->{"snmp"}->{"metadata_db_file"}); } else { $config->{"snmp"}->{"db_autoload"} = &ask( "Would you like to auto-load the database [non-destructive] ? (0 for no, 1 for yes) ", "1", $config->{"snmp"}->{"db_autoload"}, '^[01]$' ); if ( $config->{"snmp"}->{"db_autoload"} eq "1" ) { $config->{"snmp"}->{"autoload_metadata_db_file"} = &ask( "Enter the filename of the base XML file to load ", $confdir . "/store.xml", $config->{"snmp"}->{"autoload_metadata_db_file"}, '\.xml$' ); } } } $config->{"snmp"}->{"enable_registration"} = &ask( "Will this service register with an LS (0 for no, 1 for yes) ", "0", $config->{"snmp"}->{"enable_registration"}, '^[01]$' ); if ( $config->{"snmp"}->{"enable_registration"} eq "1" ) { my $registration_interval = $def_config->{"ls_registration_interval"}; $registration_interval = $config->{"snmp"}->{"ls_registration_interval"} if ( defined $config->{"snmp"}->{"ls_registration_interval"} ); $config->{"snmp"}->{"ls_registration_interval"} = &ask( "Interval between when LS registrations occur [in minutes] ", "30", $registration_interval, '^\d+$' ); my $ls_instance = $def_config->{"ls_instance"}; $ls_instance = $config->{"snmp"}->{"ls_instance"} if ( defined $config->{"snmp"}->{"ls_instance"} ); $config->{"snmp"}->{"ls_instance"} = &ask( "URL of an LS to register with ", q{}, $ls_instance, '^http:\/\/' ); } $config->{"snmp"}->{"service_name"} = &ask( "Enter a name for this service ", "SNMP MA", $config->{"snmp"}->{"service_name"}, '.+' ); $config->{"snmp"}->{"service_type"} = &ask( "Enter the service type ", "MA", $config->{"snmp"}->{"service_type"}, '.+' ); $config->{"snmp"}->{"service_description"} = &ask( "Enter a service description ", "SNMP MA", $config->{"snmp"}->{"service_description"}, '.+' ); $config->{"snmp"}->{"service_accesspoint"} = &ask( "Enter the service's URI ", $accesspoint, $config->{"snmp"}->{"service_accesspoint"}, '^http:\/\/' ); return; } sub config_status_ma { my ( $config, $accesspoint, $def_config ) = @_; $config->{"status"}->{"read_only"} = &ask( "Is this service read-only (0 for no, 1 for yes) ", "0", $config->{"status"}->{"read_only"}, '^[01]$' ); $config->{"status"}->{"db_type"} = &ask( "Enter the database type to read from ", "sqlite|mysql", $config->{"status"}->{"db_type"}, '(sqlite|mysql)' ); if ( $config->{"status"}->{"db_type"} eq "sqlite" ) { $config->{"status"}->{"db_file"} = &ask( "Enter the filename of the SQLite database ", "status.db", $config->{"status"}->{"db_file"}, '.+' ); $tmp = &ask( "Enter the table in the database to use ", "link_status", $config->{"status"}->{"db_table"}, '.+' ); $config->{"status"}->{"db_table"} = $tmp if ($tmp); } elsif ( $config->{"status"}->{"db_type"} eq "mysql" ) { $config->{"status"}->{"db_name"} = &ask( "Enter the name of the MySQL database ", q{}, $config->{"status"}->{"db_name"}, '.+' ); $config->{"status"}->{"db_host"} = &ask( "Enter the host for the MySQL database ", "localhost", $config->{"status"}->{"db_host"}, '.+' ); $tmp = &ask( "Enter the port for the MySQL database (leave blank for the default)", q{}, $config->{"status"}->{"db_port"}, '^\d*$' ); $config->{"status"}->{"db_port"} = $tmp if ($tmp); $tmp = &ask( "Enter the username for the MySQL database (leave blank for none) ", q{}, $config->{"status"}->{"db_username"}, q{} ); $config->{"status"}->{"db_username"} = $tmp if ($tmp); $tmp = &ask( "Enter the password for the MySQL database (leave blank for none) ", q{}, $config->{"status"}->{"db_password"}, q{} ); $config->{"status"}->{"db_password"} = $tmp if ($tmp); $tmp = &ask( "Enter the table in the database to use (leave blank for the default) ", "link_status", $config->{"status"}->{"db_table"}, q{} ); $config->{"status"}->{"db_table"} = $tmp if ($tmp); } $config->{"status"}->{"enable_registration"} = &ask( "Will this service register with an LS (0 for no, 1 for yes) ", "0", $config->{"status"}->{"enable_registration"}, '^[01]$' ); if ( $config->{"status"}->{"enable_registration"} eq "1" ) { my $registration_interval = $def_config->{"ls_registration_interval"}; $registration_interval = $config->{"status"}->{"ls_registration_interval"} if ( defined $config->{"status"}->{"ls_registration_interval"} ); $config->{"status"}->{"ls_registration_interval"} = &ask( "Interval between when LS registrations occur [in minutes] ", "30", $registration_interval, '^\d+$' ); my $ls_instance = $def_config->{"ls_instance"}; $ls_instance = $config->{"status"}->{"ls_instance"} if ( defined $config->{"status"}->{"ls_instance"} ); $config->{"status"}->{"ls_instance"} = &ask( "URL of an LS to register with ", q{}, $ls_instance, '^http:\/\/' ); $config->{"status"}->{"service_name"} = &ask( "Enter a name for this service ", "Link Status MA", $config->{"status"}->{"service_name"}, '.+' ); $config->{"status"}->{"service_type"} = &ask( "Enter the service type ", "MA", $config->{"status"}->{"service_type"}, '.+' ); $config->{"status"}->{"service_description"} = &ask( "Enter a service description ", "Link Status MA", $config->{"status"}->{"service_description"}, '.+' ); $config->{"status"}->{"service_accesspoint"} = &ask( "Enter the service's URI ", $accesspoint, $config->{"status"}->{"service_accesspoint"}, '^http:\/\/' ); } return; } sub config_circuitstatus_ma { my ( $config, $accesspoint, $def_config ) = @_; $config->{"circuitstatus"}->{"circuits_file_type"} = "file"; $config->{"circuitstatus"}->{"circuits_file"} = &ask( "Enter the file to get link information from ", q{}, $config->{"circuitstatus"}->{"circuits_file"}, '.+' ); $config->{"circuitstatus"}->{"status_ma_type"} = &ask( "Enter the MA to get status information from ", "sqlite|mysql", $config->{"circuitstatus"}->{"status_ma_type"}, '(sqlite|mysql|ma|ls)' ); if ( $config->{"circuitstatus"}->{"status_ma_type"} eq "ma" ) { $config->{"circuitstatus"}->{"status_ma_uri"} = &ask( "Enter the URI of the Status MA ", q{}, $config->{"circuitstatus"}->{"status_ma_uri"}, '^http' ); } elsif ( $config->{"circuitstatus"}->{"status_ma_type"} eq "ls" ) { my $ls = $def_config->{"ls_instance"}; $ls = $config->{"circuitstatus"}->{"ls_instance"} if ( defined $config->{"circuitstatus"}->{"ls_instance"} ); $config->{"circuitstatus"}->{"ls_instance"} = &ask( "Enter the URI of the LS to get MA information from ", q{}, $ls, '^http' ); } elsif ( $config->{"circuitstatus"}->{"status_ma_type"} eq "sqlite" ) { $config->{"circuitstatus"}->{"status_ma_name"} = &ask( "Enter the filename of the SQLite database ", q{}, $config->{"status"}->{"status_ma_name"}, '.+' ); $config->{"circuitstatus"}->{"status_ma_table"} = &ask( "Enter the table in the database to use ", "link_status", $config->{"status"}->{"status_ma_table"}, '.+' ); } elsif ( $config->{"circuitstatus"}->{"status_ma_type"} eq "mysql" ) { $config->{"status"}->{"status_ma_name"} = &ask( "Enter the name of the MySQL database ", q{}, $config->{"status"}->{"status_ma_name"}, '.+' ); $config->{"status"}->{"status_ma_host"} = &ask( "Enter the host for the MySQL database ", "localhost", $config->{"status"}->{"status_ma_host"}, '.+' ); $tmp = &ask( "Enter the port for the MySQL database (leave blank for the default)", q{}, $config->{"status"}->{"status_ma_port"}, '^\d*$' ); $config->{"status"}->{"status_ma_port"} = $tmp if ($tmp); $tmp = &ask( "Enter the username for the MySQL database (leave blank for none) ", q{}, $config->{"status"}->{"status_ma_username"}, q{} ); $config->{"status"}->{"status_ma_username"} = $tmp if ($tmp); $tmp = &ask( "Enter the password for the MySQL database (leave blank for none) ", q{}, $config->{"status"}->{"status_ma_password"}, q{} ); $config->{"status"}->{"status_ma_password"} = $tmp if ($tmp); $config->{"circuitstatus"}->{"status_ma_table"} = &ask( "Enter the table in the database to use ", "link_status", $config->{"status"}->{"status_ma_table"}, '.+' ); } $config->{"circuitstatus"}->{"topology_ma_type"} = &ask( "Enter the MA to get Topology information from ", "sqlite|mysql", $config->{"circuitstatus"}->{"topology_ma_type"}, '(xml|ma|none)' ); $config->{"circuitstatus"}->{"topology_ma_type"} = lc( $config->{"circuitstatus"}->{"topology_ma_type"} ); if ( $config->{"circuitstatus"}->{"topology_ma_type"} eq "xml" ) { $config->{"topology"}->{"topology_ma_name"} = &ask( "Enter the directory of the XML database ", q{}, $config->{"topology"}->{"topology_ma_name"}, '.+' ); $config->{"topology"}->{"topology_ma_file"} = &ask( "Enter the filename of the XML database ", q{}, $config->{"topology"}->{"topology_ma_file"}, '.+' ); } elsif ( $config->{"circuitstatus"}->{"topology_ma_type"} eq "ma" ) { $config->{"circuitstatus"}->{"topology_ma_uri"} = &ask( "Enter the URI of the Status MA ", q{}, $config->{"circuitstatus"}->{"topology_ma_uri"}, '^http' ); } $config->{"circuitstatus"}->{"cache_length"} = &ask( "Enter length of time to cache 'current' results ", q{}, $config->{"circuitstatus"}->{"cache_length"}, '^\d+$' ); if ( $config->{"circuitstatus"}->{"cache_length"} > 0 ) { $config->{"circuitstatus"}->{"cache_file"} = &ask( "Enter file to cache 'current' results in ", q{}, $config->{"circuitstatus"}->{"cache_file"}, '.+' ); } $config->{"circuitstatus"}->{"max_recent_age"} = &ask( "Enter age in seconds at which a result is considered stale ", q{}, $config->{"circuitstatus"}->{"max_recent_age"}, '^\d+$' ); return; } sub config_topology_ma { my ( $config, $accesspoint, $def_config ) = @_; $config->{"topology"}->{"db_type"} = "xml"; $config->{"topology"}->{"read_only"} = &ask( "Is this service read-only (0 for no, 1 for yes) ", "1", $config->{"topology"}->{"read_only"}, '^[01]$' ); $config->{"topology"}->{"db_environment"} = &ask( "Enter the directory of the XML database ", q{}, $config->{"topology"}->{"db_environment"}, '.+' ); $config->{"topology"}->{"db_file"} = &ask( "Enter the filename of the XML database ", q{}, $config->{"topology"}->{"db_file"}, '.+' ); $config->{"topology"}->{"enable_registration"} = &ask( "Will this service register with an LS (0 for no, 1 for yes) ", "0", $config->{"topology"}->{"enable_registration"}, '^[01]$' ); if ( $config->{"topology"}->{"enable_registration"} eq "1" ) { my $registration_interval = $def_config->{"ls_registration_interval"}; $registration_interval = $config->{"topology"}->{"ls_registration_interval"} if ( defined $config->{"topology"}->{"ls_registration_interval"} ); $config->{"topology"}->{"ls_registration_interval"} = &ask( "Interval between when LS registrations occur [in minutes] ", "30", $registration_interval, '^\d+$' ); my $ls_instance = $def_config->{"ls_instance"}; $ls_instance = $config->{"topology"}->{"ls_instance"} if ( defined $config->{"topology"}->{"ls_instance"} ); $config->{"topology"}->{"ls_instance"} = &ask( "URL of an LS to register with ", q{}, $ls_instance, '^http:\/\/' ); $config->{"topology"}->{"service_name"} = &ask( "Enter a name for this service ", "Topology MA", $config->{"topology"}->{"service_name"}, '.+' ); $config->{"topology"}->{"service_type"} = &ask( "Enter the service type ", "MA", $config->{"topology"}->{"service_type"}, '.+' ); $config->{"topology"}->{"service_description"} = &ask( "Enter a service description ", "Topology MA", $config->{"topology"}->{"service_description"}, '.+' ); $config->{"topology"}->{"service_accesspoint"} = &ask( "Enter the service's URI ", $accesspoint, $config->{"topology"}->{"service_accesspoint"}, '^http:\/\/' ); } return; } sub ask { my ( $prompt, $value, $prev_value, $regex ) = @_; my $result; do { print $prompt; if ( defined $prev_value ) { print "[", $prev_value, "]"; } elsif ( defined $value ) { print "[", $value, "]"; } print ": "; local $| = 1; local $_ = ; chomp; if ( defined $_ and $_ ne q{} ) { $result = $_; } elsif ( defined $prev_value ) { $result = $prev_value; } elsif ( defined $value ) { $result = $value; } else { $result = q{}; } } while ( $regex and ( not $result =~ /$regex/mx ) ); return $result; } sub SaveConfig_mine { my ( $file, $hash ) = @_; my $fh; if ( open( $fh, ">", $file ) ) { printValue( $fh, q{}, $hash, -4 ); if ( close($fh) ) { return 0; } } return -1; } sub printSpaces { my ( $fh, $count ) = @_; while ( $count > 0 ) { print $fh " "; $count--; } return; } sub printScalar { my ( $fileHandle, $name, $value, $depth ) = @_; printSpaces( $fileHandle, $depth ); if ( $value =~ /\n/mx ) { my @lines = split( $value, '\n' ); print $fileHandle "$name <\n"; printValue( $fileHandle, q{}, $value->{$elm}, $depth + 4 ); printSpaces( $fileHandle, $depth ); print $fileHandle "\n"; } } else { if ($name) { printSpaces( $fileHandle, $depth ); print $fileHandle "<$name>\n"; } foreach my $elm ( sort keys %{$value} ) { printValue( $fileHandle, $elm, $value->{$elm}, $depth + 4 ); } if ($name) { printSpaces( $fileHandle, $depth ); print $fileHandle "\n"; } } return; } } __END__ =head1 SEE ALSO L, L, L To join the 'perfSONAR-PS' mailing list, please visit: https://mail.internet2.edu/wws/info/i2-perfsonar The perfSONAR-PS subversion repository is located at: https://svn.internet2.edu/svn/perfSONAR-PS Questions and comments can be directed to the author, or the mailing list. Bugs, feature requests, and improvements can be directed here: https://bugs.internet2.edu/jira/browse/PSPS =head1 VERSION $Id$ =head1 AUTHOR Jason Zurawski, zurawski@internet2.edu Aaron Brown, aaron@internet2.edu =head1 LICENSE You should have received a copy of the Internet2 Intellectual Property Framework along with this software. If not, see =head1 COPYRIGHT Copyright (c) 2004-2008, Internet2 and the University of Delaware All rights reserved. =cut