| 11 | rodolico | 1 | #!/usr/bin/env perl
 | 
        
           |  |  | 2 |   | 
        
           | 16 | rodolico | 3 | use warnings;
 | 
        
           | 26 | rodolico | 4 | use strict;
 | 
        
           | 16 | rodolico | 5 |   | 
        
           | 45 | rodolico | 6 | # v1.1.0 20161022 RWR
 | 
        
           |  |  | 7 | # use library sysinfoconf.pm for loading, editing and displaying config
 | 
        
           | 77 | rodolico | 8 | #
 | 
        
           |  |  | 9 | # v1.2.0 20190108 RWR
 | 
        
           |  |  | 10 | # added UUID
 | 
        
           | 129 | rodolico | 11 | #
 | 
        
           |  |  | 12 | # v1.3.0 20191107 RWR
 | 
        
           |  |  | 13 | # changed the screen to allow the user to see most of the values and decide what to edit
 | 
        
           |  |  | 14 | # then write the results.
 | 
        
           |  |  | 15 | # also, parameters are passed that allow the import of a file in old conf format
 | 
        
           | 20 | rodolico | 16 |   | 
        
           | 129 | rodolico | 17 | use Getopt::Long;
 | 
        
           | 45 | rodolico | 18 |   | 
        
           | 129 | rodolico | 19 |   | 
        
           |  |  | 20 | our $VERSION = '1.3.0';
 | 
        
           |  |  | 21 |   | 
        
           | 21 | rodolico | 22 | # find our location and use it for searching for libraries
 | 
        
           |  |  | 23 | BEGIN {
 | 
        
           |  |  | 24 |    use FindBin;
 | 
        
           |  |  | 25 |    use File::Spec;
 | 
        
           |  |  | 26 |    use lib File::Spec->catdir($FindBin::Bin);
 | 
        
           | 11 | rodolico | 27 | }
 | 
        
           |  |  | 28 |   | 
        
           | 21 | rodolico | 29 | use sysinfoconf; # a library of shared routines with install.pl
 | 
        
           | 16 | rodolico | 30 |   | 
        
           | 45 | rodolico | 31 | my $config;
 | 
        
           | 16 | rodolico | 32 |   | 
        
           | 12 | rodolico | 33 | sub findSendEmail {
 | 
        
           |  |  | 34 |    my $currentLocation = shift;
 | 
        
           | 53 | rodolico | 35 |    my @possibles = ( 
 | 
        
           |  |  | 36 |             '/usr/local/opt/sendEmail/sendEmail',
 | 
        
           |  |  | 37 |             '/usr/local/opt/sendEmail/sendEmail.pl',
 | 
        
           |  |  | 38 |             '/opt/sendEmail/sendEmail', 
 | 
        
           |  |  | 39 |             '/opt/sendEmail/sendEmail.pl' 
 | 
        
           |  |  | 40 |             );
 | 
        
           | 12 | rodolico | 41 |    return $currentLocation if ( $currentLocation && -x $currentLocation );
 | 
        
           |  |  | 42 |    # well, we didn't find it, so look around some more
 | 
        
           | 104 | rodolico | 43 |    # Look through the possibles
 | 
        
           | 12 | rodolico | 44 |    foreach my $current ( @possibles ) {
 | 
        
           |  |  | 45 |       return $current if -x $current;
 | 
        
           |  |  | 46 |    }
 | 
        
           |  |  | 47 |    if ( &yesno( "You are asking for sendEmail, but I don't see it on the system\nWould you like me to automatically download and install" ) ) {
 | 
        
           | 28 | rodolico | 48 |       my $path = `perl getSendEmail.pl`;
 | 
        
           | 12 | rodolico | 49 |       chomp $path;
 | 
        
           |  |  | 50 |       return $path;
 | 
        
           |  |  | 51 |    }
 | 
        
           |  |  | 52 |    return '';
 | 
        
           |  |  | 53 | }
 | 
        
           |  |  | 54 |   | 
        
           | 11 | rodolico | 55 | sub userConfirmation {
 | 
        
           | 45 | rodolico | 56 |    my $config = shift;
 | 
        
           | 11 | rodolico | 57 |   | 
        
           |  |  | 58 | }
 | 
        
           |  |  | 59 |   | 
        
           | 16 | rodolico | 60 | sub setUpTransport {
 | 
        
           |  |  | 61 |    my ($priority, $transport, $fields, $type ) = @_;
 | 
        
           |  |  | 62 |    $priority = getAnswer( 'Priority', $priority );
 | 
        
           |  |  | 63 |    $$transport{'sendScript'} = $$fields{'sendScript'} unless $$transport{'sendScript'};
 | 
        
           | 108 | rodolico | 64 |    $$transport{'name'} = $type unless $$transport{'name'};
 | 
        
           | 16 | rodolico | 65 |    my $allKeys = $$fields{'keys'};
 | 
        
           |  |  | 66 |    foreach my $key ( @$allKeys ) {
 | 
        
           |  |  | 67 |       if ( $key eq 'sendEmailScriptLocation' && ! -e $$transport{$key} ) {
 | 
        
           | 28 | rodolico | 68 |          my $temp = &findSendEmail( $$transport{$key} );
 | 
        
           | 16 | rodolico | 69 |          $$transport{$key} = $temp if $temp;
 | 
        
           |  |  | 70 |       }
 | 
        
           |  |  | 71 |       $$transport{$key} = &getAnswer( "$key ", $$transport{$key} ? $$transport{$key} : '' );
 | 
        
           |  |  | 72 |    }
 | 
        
           |  |  | 73 |    return ( $priority, $transport );
 | 
        
           |  |  | 74 | }
 | 
        
           |  |  | 75 |   | 
        
           |  |  | 76 | sub showAllTransports {
 | 
        
           |  |  | 77 |    foreach my $priority ( sort { $a <=> $b } keys %$transports ) {
 | 
        
           |  |  | 78 |       print '='x40 . "\n";
 | 
        
           |  |  | 79 |       &showTransports( $priority, $$transports{ $priority } );
 | 
        
           |  |  | 80 |       print '='x40 . "\n";
 | 
        
           |  |  | 81 |    }
 | 
        
           |  |  | 82 | }   
 | 
        
           |  |  | 83 |   | 
        
           |  |  | 84 | sub showTransports {
 | 
        
           |  |  | 85 |    my ( $priority,$thisOne )  = @_;
 | 
        
           | 108 | rodolico | 86 |    print $$thisOne{'name'} . " has priority $priority\n";
 | 
        
           | 16 | rodolico | 87 |    foreach my $key ( sort keys %$thisOne ) {
 | 
        
           |  |  | 88 |       next if $key =~ m/^-.*-$/;
 | 
        
           |  |  | 89 |       print "$key = $$thisOne{$key}\n";
 | 
        
           |  |  | 90 |    }
 | 
        
           |  |  | 91 | }
 | 
        
           |  |  | 92 |   | 
        
           |  |  | 93 | sub doTransports {
 | 
        
           |  |  | 94 |    my ( $transports ) = @_;
 | 
        
           |  |  | 95 |   | 
        
           |  |  | 96 |    foreach my $priority ( sort { $a <=> $b } keys %$transports ) {
 | 
        
           | 108 | rodolico | 97 |       if ( &yesno( $$transports{$priority}{'name'} . " has a priority of $priority, edit it?") ) {
 | 
        
           |  |  | 98 |          #print Dumper( $sendTypes{$$transports{$priority}{'name'}} );
 | 
        
           | 16 | rodolico | 99 |          #die;
 | 
        
           | 108 | rodolico | 100 |          my ( $newpriority,$temp ) = &setUpTransport( $priority, $$transports{$priority}, $sendTypes{$$transports{$priority}{'name'}} );
 | 
        
           | 16 | rodolico | 101 |          if ( $newpriority != $priority ) {
 | 
        
           |  |  | 102 |             delete $$transports{$priority};
 | 
        
           |  |  | 103 |             $priority = $newpriority;
 | 
        
           |  |  | 104 |          }
 | 
        
           |  |  | 105 |          $$transports{$priority} = $temp;
 | 
        
           |  |  | 106 |       } # if
 | 
        
           |  |  | 107 |    }
 | 
        
           |  |  | 108 |   | 
        
           |  |  | 109 |    foreach my $priority ( sort { $a <=> $b } keys %$transports ) {
 | 
        
           |  |  | 110 |       print '='x40 . "\n";
 | 
        
           |  |  | 111 |       &showTransports( $priority, $$transports{ $priority } );
 | 
        
           |  |  | 112 |       print '='x40 . "\n";
 | 
        
           |  |  | 113 |    }
 | 
        
           |  |  | 114 |   | 
        
           |  |  | 115 |    while ( &yesno( "Would you like to add any other transport mechanisms?" ) ) {
 | 
        
           | 28 | rodolico | 116 |       my $newType = &getAnswer( 'Type of Transport? ', keys %sendTypes );
 | 
        
           | 16 | rodolico | 117 |       my ( $priority,$temp ) = &setUpTransport( 99, {}, $sendTypes{$newType}, $newType );
 | 
        
           |  |  | 118 |       $$transports{$priority} = $temp;
 | 
        
           |  |  | 119 |    }
 | 
        
           |  |  | 120 |   | 
        
           |  |  | 121 |    foreach my $priority ( sort { $a <=> $b } keys %$transports ) {
 | 
        
           |  |  | 122 |       print '='x40 . "\n";
 | 
        
           |  |  | 123 |       &showTransports( $priority, $$transports{ $priority } );
 | 
        
           |  |  | 124 |       print '='x40 . "\n";
 | 
        
           |  |  | 125 |    }
 | 
        
           |  |  | 126 | }
 | 
        
           |  |  | 127 |   | 
        
           | 129 | rodolico | 128 | sub showEntry {
 | 
        
           |  |  | 129 |    my ( $lineno, $prompt, $value ) = @_;
 | 
        
           |  |  | 130 |    $value = '' unless $value;
 | 
        
           |  |  | 131 |    return "$lineno. $prompt: $value\n";
 | 
        
           |  |  | 132 | }
 | 
        
           | 16 | rodolico | 133 |   | 
        
           | 129 | rodolico | 134 | sub displayEditScreen {
 | 
        
           |  |  | 135 |    my $config = shift;
 | 
        
           |  |  | 136 |    #print "\033[2J";    #clear the screen
 | 
        
           |  |  | 137 |    #print "\033[0;0H"; #jump to 0,0   
 | 
        
           |  |  | 138 |    print &showEntry( 1, 'Client Name', $config->{'clientName'} );
 | 
        
           |  |  | 139 |    print &showEntry( 2, 'Host Name', $config->{'hostname'} );
 | 
        
           |  |  | 140 |    print &showEntry( 3, 'Serial Number', $config->{'serialNumber'} );
 | 
        
           |  |  | 141 |    print &showEntry( 4, 'UUID', $config->{'UUID'} );
 | 
        
           |  |  | 142 |    print &showEntry( 5, 'Module Dirs', join( ',', $config->{'moduleDirs'} ?  @{ $config->{'moduleDirs'} } : () ) );
 | 
        
           |  |  | 143 |    print &showEntry( 6, 'Script Dirs', join( ',', $config->{'scriptDirs'} ?  @{ $config->{'scriptDirs'} } : () ) );
 | 
        
           |  |  | 144 |    print &showEntry( 7, 'Transports', '' );
 | 
        
           |  |  | 145 |    foreach my $key ( sort { $a <=> $b } keys %{ $config->{'transports'} } ) {
 | 
        
           |  |  | 146 |       print "\t$key\t" . $config->{'transports'}->{$key}->{'name'} . "\n";
 | 
        
           |  |  | 147 |    }
 | 
        
           |  |  | 148 |    print "Select Option to Edit, or 'Done' if finished [Done]: ";
 | 
        
           |  |  | 149 |    my $selection = <>;
 | 
        
           |  |  | 150 |    chomp $selection;
 | 
        
           |  |  | 151 |    $selection = 'd' unless $selection;
 | 
        
           |  |  | 152 |    return lc substr( $selection, 0, 1 );
 | 
        
           |  |  | 153 | }
 | 
        
           | 45 | rodolico | 154 |   | 
        
           | 129 | rodolico | 155 | sub getValue {
 | 
        
           |  |  | 156 |    my ( $prompt, $value ) = @_;
 | 
        
           |  |  | 157 |    print "$prompt [$value]: ";
 | 
        
           |  |  | 158 |    my $t = <>;
 | 
        
           |  |  | 159 |    chomp $t;
 | 
        
           |  |  | 160 |    return $t ? $t : $value;
 | 
        
           |  |  | 161 | }
 | 
        
           | 104 | rodolico | 162 |   | 
        
           | 129 | rodolico | 163 | sub editSelection {
 | 
        
           |  |  | 164 |    my $selection = shift;
 | 
        
           |  |  | 165 |    if ( $selection == 1 ) {
 | 
        
           |  |  | 166 |       $config->{'clientName'} = &getValue( 'Client Name', $config->{'clientName'} );
 | 
        
           |  |  | 167 |    } elsif ( $selection == 2 ) {
 | 
        
           |  |  | 168 |       $config->{'hostname'} = &getValue( 'Host Name', $config->{'hostname'} );
 | 
        
           |  |  | 169 |    } elsif ( $selection == 3 ) {
 | 
        
           |  |  | 170 |       $config->{'serialNumber'} = &getValue( 'Serial Number', $config->{'serialNumber'} );
 | 
        
           |  |  | 171 |    } elsif ( $selection == 4 ) {
 | 
        
           |  |  | 172 |       $config->{'UUID'} = &getValue( 'UUID', $config->{'UUID'} );
 | 
        
           |  |  | 173 |    } elsif ( $selection == 5 ) {
 | 
        
           |  |  | 174 |       my $t = join( ',', $config->{'moduleDirs'} ?  @{ $config->{'moduleDirs'} } : () );
 | 
        
           |  |  | 175 |       $t = &getValue( "Comma separated list of Module Directories\n\t", $t );
 | 
        
           |  |  | 176 |       my @t = split( ',', $t );
 | 
        
           |  |  | 177 |       $config->{'moduleDirs'} =  \@t;
 | 
        
           |  |  | 178 |    } elsif ( $selection == 6 ) {
 | 
        
           |  |  | 179 |       my $t = join( ',', $config->{'scriptDirs'} ?  @{ $config->{'scriptDirs'} } : () );
 | 
        
           |  |  | 180 |       $t = &getValue( "Comma separated list of Script Directories\n\t", $t );
 | 
        
           |  |  | 181 |       my @t = split( ',', $t );
 | 
        
           |  |  | 182 |       $config->{'scriptDirs'} =  \@t;
 | 
        
           |  |  | 183 |    } elsif ( $selection == 7 ) {
 | 
        
           |  |  | 184 |       print "Can not automatically do this at this time\nManually edit the file (press enter to continue)";
 | 
        
           |  |  | 185 |       my $t = <>;
 | 
        
           |  |  | 186 |    }
 | 
        
           |  |  | 187 | }
 | 
        
           |  |  | 188 |   | 
        
           | 132 | rodolico | 189 | sub help {
 | 
        
           |  |  | 190 |    print "$0 version $VERSION\n";
 | 
        
           |  |  | 191 |    print "Reads one or more sysinfo configuration file and\nallows user to edit the values\n\n";
 | 
        
           |  |  | 192 |    print "$0 --verbose --file=/full/paht/to/input -output=/full/path/to/sysinfo-client.yaml\n";
 | 
        
           |  |  | 193 |    print "   --verbose may be entered more than one time to increase verbosity\n";
 | 
        
           |  |  | 194 |    print "   --file may be entered multiple times and may contain a comma delimited group of files\n";
 | 
        
           |  |  | 195 |    print "   --output is the file which will be written to\n\n";
 | 
        
           |  |  | 196 |    print "All parameters are optional\n";
 | 
        
           |  |  | 197 |    print "Will search common locations for sysinfo-client.yaml and, if found, append this to the end\n";
 | 
        
           |  |  | 198 |    print "of the input file list.\n";
 | 
        
           |  |  | 199 |    print "If no --output is passed, will write to the last --file passed or the file which was found\n";
 | 
        
           |  |  | 200 |    print "in the search\n";
 | 
        
           |  |  | 201 |    print "All parameters accept the short flag, ie -v, -f, -o and -h\n";
 | 
        
           |  |  | 202 |    exit;
 | 
        
           |  |  | 203 | }
 | 
        
           |  |  | 204 |   | 
        
           |  |  | 205 |   | 
        
           | 129 | rodolico | 206 | my @confFileName;
 | 
        
           | 132 | rodolico | 207 | my $outputFile;
 | 
        
           | 129 | rodolico | 208 | my $verbose;
 | 
        
           |  |  | 209 | my $help;
 | 
        
           |  |  | 210 | my $version;
 | 
        
           |  |  | 211 |   | 
        
           |  |  | 212 | # handle any command line parameters that may have been passed in
 | 
        
           |  |  | 213 | # verbose is incremental, so for example, -vv would give more info than -v
 | 
        
           |  |  | 214 | # there can be multiple files passed, and an entry can have a comma
 | 
        
           |  |  | 215 | # separated list. The files will be processed in order, with the last
 | 
        
           |  |  | 216 | # one passed in being the one that overrides everything.
 | 
        
           |  |  | 217 | GetOptions (
 | 
        
           | 132 | rodolico | 218 |             "verbose|v+"  => \$verbose, # verbosity level, 0-9
 | 
        
           |  |  | 219 |             'file|f=s'    => \@confFileName, # array of files to read
 | 
        
           |  |  | 220 |             'output|o=s'  => \$outputFile, # file to save to
 | 
        
           | 129 | rodolico | 221 |             'help|h'      => \$help
 | 
        
           |  |  | 222 |             ) or die "Error parsing command line\n";
 | 
        
           |  |  | 223 |   | 
        
           |  |  | 224 | if ( $help ) { &help() ; exit; }
 | 
        
           |  |  | 225 |   | 
        
           |  |  | 226 | # if they passed something like -f file1,file2,file3, parse it out
 | 
        
           |  |  | 227 | @confFileName = split(/,/,join(',',@confFileName));
 | 
        
           |  |  | 228 |   | 
        
           |  |  | 229 | # look for the standard configuration file in the standard place
 | 
        
           | 103 | rodolico | 230 | ( $confDir, $sysinfo3 ) = &findConf( $sysinfo3 );
 | 
        
           | 129 | rodolico | 231 | # add it at the tail end of the list
 | 
        
           |  |  | 232 | push @confFileName, $confDir . "/" . $sysinfo3 if ( $confDir );
 | 
        
           | 132 | rodolico | 233 | $outputFile = $confFileName[-1] unless $outputFile;
 | 
        
           | 53 | rodolico | 234 |   | 
        
           | 129 | rodolico | 235 | print "Loading defaults from existing configs\n";
 | 
        
           |  |  | 236 | $config = &makeConfig( @confFileName  );
 | 
        
           | 104 | rodolico | 237 |   | 
        
           | 129 | rodolico | 238 | my $selection;
 | 
        
           |  |  | 239 | while ( ( $selection = &displayEditScreen( $config ) ) ne 'd' ) {
 | 
        
           |  |  | 240 |    &editSelection( $selection );
 | 
        
           | 11 | rodolico | 241 | }
 | 
        
           |  |  | 242 |   | 
        
           | 132 | rodolico | 243 | if ( &yesno( "Ready to write configuration to $outputFile, ok?" ) ) {
 | 
        
           |  |  | 244 |    &writeConfig( $outputFile, &showConf( $config ) );
 | 
        
           |  |  | 245 | }
 | 
        
           | 20 | rodolico | 246 |   | 
        
           | 45 | rodolico | 247 | #use Data::Dumper;
 | 
        
           |  |  | 248 | #print Dumper( $config ); die;
 | 
        
           | 16 | rodolico | 249 |   | 
        
           | 132 | rodolico | 250 | #&doTransports( $$config{'transports'} );
 | 
        
           | 11 | rodolico | 251 |   | 
        
           |  |  | 252 |   | 
        
           |  |  | 253 | 1;
 |