Author: arkurth
Date: Tue Sep 14 19:15:54 2010
New Revision: 997046

URL: http://svn.apache.org/viewvc?rev=997046&view=rev
Log:
VCL-164
Added setup() and setup_add_local_account() to Module.pm to allow local 
accounts to be added via 'vcld -setup'.  Updated utils.pm::get_user_info() to 
accept an optional affiliation identifier argument because.  The user.unityid 
column is not unique, but user.unityid+user.affiliationid must be unique.  This 
argument allows the affiliation to be specified so that a single user is found 
even if the same unityid is used for different affiliations.

Other
Changed utils.pm::format_data to use Data::Dumper.  The old subroutine was very 
difficult to debug/maintain and Data::Dumper performs the same function.

Removed progressive delay in between failed SSH attempts in 
utils.pm::run_ssh_command.  The progressive delay never added any benefit, but 
delayed a process before it failed.

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/Module.pm
    incubator/vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module.pm?rev=997046&r1=997045&r2=997046&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/Module.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/Module.pm Tue Sep 14 19:15:54 
2010
@@ -83,8 +83,9 @@ use strict;
 use warnings;
 use diagnostics;
 use English '-no_match_vars';
+use Digest::SHA1 qw(sha1_hex);
 
-use VCL::utils qw($SETUP_MODE $VERBOSE %ERRORS &notify &getnewdbh format_data);
+use VCL::utils;
 use VCL::DataStructure;
 use VCL::Module::Semaphore;
 
@@ -499,6 +500,176 @@ sub get_semaphore {
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 setup
+
+ Parameters  : none
+ Returns     : 
+ Description : This subroutine is used when vcld is run in setup mode. It
+               presents a menu for overall VCL configuration settings.
+
+=cut
+
+sub setup {
+       my $self = shift;
+       unless (ref($self) && $self->isa('VCL::Module')) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       push @{$ENV{setup_path}}, 'User Accounts';
+       
+       my @operation_choices = (
+               'Add Local VCL User Account',
+       );
+       
+       my @setup_path = @{$ENV{setup_path}};
+       OPERATION: while (1) {
+               @{$ENV{setup_path}} = @setup_path;
+               
+               print '-' x 76 . "\n";
+               
+               print "Choose an operation:\n";
+               my $operation_choice_index = 
setup_get_array_choice(@operation_choices);
+               last if (!defined($operation_choice_index));
+               my $operation_name = 
$operation_choices[$operation_choice_index];
+               print "\n";
+               
+               push @{$ENV{setup_path}}, $operation_name;
+               
+               if ($operation_name =~ /add local/i) {
+                       $self->setup_add_local_account();
+               }
+       }
+       
+       pop @{$ENV{setup_path}};
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 setup_add_local_account
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Presents an interface to create a local VCL user account. This
+               subroutine is executed when vcld is run with the -setup 
argument.
+
+=cut
+
+sub setup_add_local_account {
+       my $self = shift;
+       unless (ref($self) && $self->isa('VCL::Module')) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       #myusername', 'myfirstname', 'mylastname', 'myemailaddr',
+       
+       # Get the username (user.unityid)
+       my $username;
+       while (!$username) {
+               $username = setup_get_input_string("Enter the user login name");
+               return if (!defined($username));
+               
+               # Check format of username
+               if ($username !~ /^[\w\-_]+$/i) {
+                       print "User name is not valid: '$username'\n\n";
+                       $username = undef;
+               }
+               
+               # Make sure username does not already exist
+               my $user_info = get_user_info($username, 'Local');
+               if ($user_info && $user_info->{unityid} eq $username) {
+                       print "Local VCL user account already exists: 
$username\n\n";
+                       $username = undef;
+               }
+       }
+       print "\n";
+       
+       # Get the other required information
+       my $first_name;
+       while (!$first_name) {
+               $first_name = setup_get_input_string("Enter the first name");
+               return if (!defined($first_name));
+       }
+       print "\n";
+       
+       my $last_name;
+       while (!$last_name) {
+               $last_name = setup_get_input_string("Enter the last name");
+               return if (!defined($last_name));
+       }
+       print "\n";
+       
+       my $email_address;
+       while (!defined($email_address)) {
+               $email_address = setup_get_input_string("Enter the email 
address", 'not set');
+               return if (!defined($email_address));
+               
+               # Check format of the email address
+               if ($email_address eq 'not set') {
+                       $email_address = '';
+               }
+               elsif ($email_address !~ 
/^([a-z0-9._%+...@[a-z0-9.-]+\.[a-z]{2,4}(,?))+$/i) {
+                       print "Email address is not valid: 
'$email_address'\n\n";
+                       $email_address = undef;
+               }
+       }
+       print "\n";
+       
+       my $password;
+       while (!$password) {
+               $password = setup_get_input_string("Enter the password");
+               return if (!defined($password));
+       }
+       print "\n";
+       
+       # Generate an 8-character random string
+       my @characters = ("a" .. "z", "A" .. "Z", "0" .. "9");
+       my $random_string;
+       srand;
+       for (1 .. 8) {
+               $random_string .= $characters[rand((scalar(@characters) - 1))];
+       }
+       
+       # Get an SHA1 hex digest from the password and random string
+       my $digest = sha1_hex("$password$random_string");
+       
+       # Insert a row into the user table
+       my $insert_user_statement = <<EOF;
+INSERT INTO user
+(unityid, affiliationid, firstname, lastname, email, lastupdated)
+VALUES
+('$username', (SELECT id FROM affiliation WHERE name LIKE 'Local'), 
'$first_name', '$last_name', '$email_address', NOW())
+EOF
+       
+       my $user_id = database_execute($insert_user_statement);
+       if (!defined($user_id)) {
+               print "ERROR: failed to insert into user table\n";
+               return;
+       }
+       
+       # Insert a row into the localauth table
+       my $insert_localauth_statement = <<EOF;
+INSERT INTO localauth
+(userid, passhash, salt, lastupdated)
+VALUES
+($user_id, '$digest', '$random_string', NOW())
+EOF
+       
+       my $localauth_id = database_execute($insert_localauth_statement);
+       if (!defined($localauth_id)) {
+               print "ERROR: failed to insert into localauth table\n";
+               return;
+       }
+       
+       print "Local VCL user account successfully created: $username\n";
+       
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 

Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=997046&r1=997045&r2=997046&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Tue Sep 14 19:15:54 2010
@@ -70,6 +70,7 @@ use List::Util qw(min max);
 use HTTP::Headers;
 use RPC::XML::Client;
 use Scalar::Util 'blessed';
+use Data::Dumper;
 
 #use Date::Calc qw(Delta_DHMS Time_to_Date Date_to_Time);
 
@@ -5422,16 +5423,9 @@ sub run_ssh_command {
                
                # Delay performing next attempt if this isn't the first attempt
                if ($attempts > 1) {
-                       my $delay;
-                       if ($attempts == 2) {
-                               $delay = 2;
-                       }
-                       else {
-                               # Progressively increase the delay
-                               $delay = (5 * $attempts);
-                       }
-                       notify($ERRORS{'DEBUG'}, 0, "sleeping for $delay 
seconds before making next SSH attempt") if $output_level;
-                       sleep $delay;
+                       my $delay_seconds = 2;
+                       notify($ERRORS{'DEBUG'}, 0, "sleeping for 
$delay_seconds seconds before making next SSH attempt") if $output_level;
+                       sleep $delay_seconds;
                }
 
                ## Add -v (verbose) argument to command if this is the 2nd 
attempt
@@ -7918,7 +7912,7 @@ sub get_computer_grp_members {
 
 =head2 get_user_info
 
- Parameters  : $user_identifier
+ Parameters  : $user_identifier, $affiliation_identifier (optional)
  Returns     : hash reference
  Description : Retrieves user information from the database. The user 
identifier
                argument can either be a user ID or unityid. A hash reference is
@@ -7961,13 +7955,13 @@ sub get_computer_grp_members {
 =cut
 
 sub get_user_info {
-   my ($user_identifier) = @_;
+       my ($user_identifier, $affiliation_identifier) = @_;
        if (!defined($user_identifier)) {
                notify($ERRORS{'WARNING'}, 0, "user identifier argument was not 
specified");
                return;
        }
-
-   my $select_statement = <<EOF;
+       
+       my $select_statement = <<EOF;
 SELECT DISTINCT
 user.*,
 adminlevel.name AS adminlevel_name,
@@ -7985,13 +7979,25 @@ LEFT JOIN (affiliation) ON (affiliation.
 LEFT JOIN (IMtype) ON (IMtype.id = user.IMtypeid)
 WHERE
 EOF
-
+       
+       # If the user identifier is all digits match it to user.id
+       # Otherwise, match user.unityid
        if ($user_identifier =~ /^\d+$/) {
                $select_statement .= "user.id = $user_identifier";
        }
        else {
                $select_statement .= "user.unityid = '$user_identifier'";
        }
+       
+       # If the affiliation identifier argument was specified add affiliation 
table clause
+       if (defined($affiliation_identifier)) {
+               if ($affiliation_identifier =~ /^\d+$/) {
+                       $select_statement .= "\nAND affiliation.id = 
$affiliation_identifier";
+               }
+               else {
+                       $select_statement .= "\nAND affiliation.name LIKE 
'$affiliation_identifier'";
+               }
+       }
 
        # Call the database select subroutine
        # This will return an array of one or more rows based on the select 
statement
@@ -8631,98 +8637,29 @@ sub update_cluster_info {
 
 =head2 format_data
 
- Parameters  :
- Returns     : 0 or 1
- Description :
+ Parameters  : $data
+ Returns     : string
+ Description : Formats the data argument using Data::Dumper.
 
 =cut
 
 sub format_data {
+       my @data = @_;
        
-       my $return_string;
-
-       my $level = 0;
-       $level = $_[scalar(@_) - 2] if (scalar(@_) > 2 && !ref($_[scalar(@_) - 
2]));
-
-       my $name = '';
-       $name = $_[scalar(@_) - 1] if (scalar(@_) > 1 && !ref($_[scalar(@_) - 
1]));
-
-       my $type;
-       my $data;
-
-       if (ref($_[0]) eq "HASH" || (blessed($_[0]) && $_[0]->isa("HASH"))) {
-               $data = $_[0];
-               $type = '%';
-               return "%<empty>" if (keys(%{$_[0]}) == 0);
+       if (!(@data)) {
+               return '<undefined>';
        }
-       elsif (ref($_[0]) eq "ARRAY" || (blessed($_[0]) && 
$_[0]->isa("ARRAY"))) {
-               my $index = 0;
-               for (@{$_[0]}) {
-                       $data->{$index} = $_;
-                       $index++;
-               }
-               $type = '@';
-               return "@<empty>" if (@{$_[0]} == 0);
-       }
-       elsif (ref($_[0]) eq "SCALAR") {
-               $data = $_[0];
-               $type = '$';
-       }
-       else {
-               $data = \$_[0];
-               $type = '$';
-
-               $return_string .= "ref: " . ref($_[0]) . "\n";
-               $return_string .= "data: " . $_[0] . "\n";
-
-               return $return_string;
-       }
-
-       $data = 'NULL' if (!defined $data);
-
-       $return_string .= "$type$name\n";
-
-       # Loop through values
-       foreach my $key (sort {lc($a) cmp lc($b)} keys(%{$data})) {
-               my $value = $data->{$key};
-
-               $value = 'NULL' if (!defined $value);
-
-               for (my $count = 0; $count < $level; $count++) {
-                       $return_string .= "..." if ($count < $level);
-               }
-               $return_string .= "|--";
-
-               if (ref($value) eq 'SCALAR') {
-                       $value = "\\'$$value'";
-               }
-               elsif (!ref($value) && $value ne 'NULL') {
-                       $value = "'$value'";
-               }
-
-               if (!ref($value)) {
-                       if ($type eq '@') {
-                               $return_string .= "[$key] = $value\n";
-                       }
-                       elsif ($type eq '%') {
-                               $return_string .= "[$name]{$key} = $value\n";
-                       }
-               }
-               else {
-                       if ($type eq '@') {
-                               #$return_string .= "\[$key\]\n";
-                               $return_string .= format_data($value, $level + 
1, "$name\[$key\]");
-                       }
-                       elsif ($type eq '%') {
-                               #$return_string .= "\{$key\} $name\n";
-                               $return_string .= format_data($value, $level + 
1, "$name\{$key\}");
-                       }
-               } ## end else [ if (!ref($value))
-
-       } ## end foreach my $key (sort {lc($a) cmp lc($b)} keys(...
-
-       return $return_string;
-} ## end sub format_data
+       
+       $Data::Dumper::Indent    = 1;
+       $Data::Dumper::Purity    = 1;
+       $Data::Dumper::Useqq     = 1;      # Use double quotes for representing 
string values
+       $Data::Dumper::Terse     = 1;
+       $Data::Dumper::Quotekeys = 1;      # Quote hash keys
+       $Data::Dumper::Pair      = ' => '; # Specifies the separator between 
hash keys and values
+       $Data::Dumper::Sortkeys  = 1;      # Hash keys are dumped in sorted 
order
+       
+       return Dumper(@data);
+}
 
 #/////////////////////////////////////////////////////////////////////////////
 


Reply via email to