You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@vcl.apache.org by ar...@apache.org on 2010/09/14 21:15:55 UTC
svn commit: r997046 - in /incubator/vcl/trunk/managementnode/lib/VCL:
Module.pm utils.pm
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 ¬ify &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);
+}
#/////////////////////////////////////////////////////////////////////////////