Author: fapeeler Date: Wed Jun 22 19:07:53 2011 New Revision: 1138586 URL: http://svn.apache.org/viewvc?rev=1138586&view=rev Log: VCL-463
Ongoing work on server request. This portion is code related to adding a group of users. Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm incubator/vcl/trunk/managementnode/lib/VCL/healthcheck.pm incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1138586&r1=1138585&r2=1138586&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS.pm Wed Jun 22 19:07:53 2011 @@ -1661,6 +1661,113 @@ sub get_os_type { #///////////////////////////////////////////////////////////////////////////// +sub manage_server_access { + + my $self = shift; + if (ref($self) !~ /VCL::Module/i) { + notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); + return; + } + + my $computer_node_name = $self->data->get_computer_node_name() || return; + my $reservation_id = $self->data->get_reservation_id(); + my $server_request_id = $self->data->get_server_request_id(); + my $server_request_admingroupid = $self->data->get_server_request_admingroupid(); + my $server_request_logingroupid = $self->data->get_server_request_logingroupid(); + + #Build list of users. + #If in admin group set admin flag + #If in both login and admin group, only use admin setting + #Check if user is in reserverationaccounts table, add user if needed + #Check if user exists on server, add if needed + + my @userlist_admin; + my @userlist_login; + my %user_hash; + + if ( $server_request_admingroupid ) { + @userlist_admin = getusergroupmembers($server_request_admingroupid); + } + if ( $server_request_logingroupid ) { + @userlist_login = getusergroupmembers($server_request_logingroupid); + } + + if ( scalar @userlist_admin > 0 ) { + foreach my $str (@userlist_admin) { + my ($username,$uid,$vcl_user_id) = split(/:/, $str); + $user_hash{$uid}{"username"} = $username; + $user_hash{$uid}{"uid"} = $uid; + $user_hash{$uid}{"vcl_user_id"} = $vcl_user_id; + $user_hash{$uid}{"rootaccess"} = 1; + } + } + if ( scalar @userlist_login > 0 ) { + foreach my $str (@userlist_admin) { + my ($username, $uid,$vcl_user_id) = split(/:/, $str); + if (!exists($user_hash{$uid})) { + $user_hash{$uid}{"username"} = $username; + $user_hash{$uid}{"uid"} = $uid; + $user_hash{$uid}{"vcl_user_id"} = $vcl_user_id; + $user_hash{$uid}{"rootaccess"} = 0; + } + else { + notify($ERRORS{'OK'}, 0, "$uid for $username exists in user_hash, skipping"); + } + } + } + + #Collect users in reservationaccounts table + my %res_accounts = get_reservation_accounts($reservation_id); + my $not_standalone_list = ""; + my $standalone = 0; + if(defined($ENV{management_node_info}{NOT_STANDALONE}) && $ENV{management_node_info}{NOT_STANDALONE}){ + $not_standalone_list = $ENV{management_node_info}{NOT_STANDALONE}; + } + + foreach my $userid (sort keys %user_hash) { + next if (!($userid)); + if(!exists($res_accounts{$userid})){ + #check affiliation + my $affiliation_name = get_user_affiliation($userid); + if(!(grep(/$affiliation_name/, split(/,/, $not_standalone_list) ))) { + $standalone = 1; + } + + #IF standalone - generate password + if($standalone) { + $user_hash{$userid}{"passwd"} = getpw(); + } + else { + $user_hash{$userid}{"passwd"} = 0; + } + + if (!(update_reservation_accounts($reservation_id,$user_hash{$userid}{vcl_user_id},$user_hash{$userid}{passwd}))) { + notify($ERRORS{'WARNING'}, 0, "Failed to insert $reservation_id,$user_hash{$userid}{vcl_user_id},$user_hash{$userid}{passwd} into reservationsaccounts table"); + + } + + # Create user on the OS + if($self->OS->create_user($user_hash{$userid}{username},$user_hash{passwd},$user_hash{$userid}{uid},$user_hash{$userid}{rootaccess},$standalone)) { + notify($ERRORS{'OK'}, 0, "Successfully created user $user_hash{$userid}{username} on $computer_node_name"); + } + else { + notify($ERRORS{'WARNING'}, 0, "Failed to create user on $computer_node_name "); + } + + + } + else { + notify($ERRORS{'WARNING'}, 0, "$userid exists in reservationaccounts table, assuming it exists on OS"); + } + + } + + return 1; + +} + +#/////////////////////////////////////////////////////////////////////////// + 1; __END__ Modified: incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm?rev=1138586&r1=1138585&r2=1138586&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/Module/OS/Linux.pm Wed Jun 22 19:07:53 2011 @@ -823,70 +823,17 @@ sub reserve { my $computer_node_name = $self->data->get_computer_node_name(); my $image_identity = $self->data->get_image_identity; my $imagemeta_rootaccess = $self->data->get_imagemeta_rootaccess(); - my $user_standalone = $self->data->get_user_standalone(); - my $user_uid = $self->data->get_user_uid(); + my $user_uid = $self->data->get_user_uid(); if($self->add_vcl_usergroup()){ } - - my $useradd_string; - if(defined($user_uid) && $user_uid != 0){ - $useradd_string = "/usr/sbin/useradd -u $user_uid -d /home/$user_name -m $user_name -g vcl"; - } - else{ - $useradd_string = "/usr/sbin/useradd -d /home/$user_name -m $user_name -g vcl"; - } - - - my @sshcmd = run_ssh_command($computer_node_name, $image_identity, $useradd_string, "root"); - foreach my $l (@{$sshcmd[1]}) { - if ($l =~ /$user_name exists/) { - notify($ERRORS{'OK'}, 0, "detected user already has account"); - if ($self->delete_user()) { - notify($ERRORS{'OK'}, 0, "user has been deleted from $computer_node_name"); - @sshcmd = run_ssh_command($computer_node_name, $image_identity, $useradd_string, "root"); - } - } + + if (!$self->create_user()) { + notify($ERRORS{'CRITICAL'}, 0, "Failed to add user $user_name to $computer_node_name"); + return 0; } - - if ($user_standalone) { - notify($ERRORS{'DEBUG'}, 0, "Standalone user setting single-use password"); - my $reservation_password = $self->data->get_reservation_password(); - - #Set password - if ($self->changepasswd($computer_node_name, $user_name, $reservation_password)) { - notify($ERRORS{'OK'}, 0, "Successfully set password on useracct: $user_name on $computer_node_name"); - } - else { - notify($ERRORS{'CRITICAL'}, 0, "Failed to set password on useracct: $user_name on $computer_node_name"); - return 0; - } - } ## end if ($user_standalone) - - - #Check image profile for allowed root access - if ($imagemeta_rootaccess) { - # Add to sudoers file - #clear user from sudoers file to prevent dups - my $clear_cmd = "sed -i -e \"/^$user_name .*/d\" /etc/sudoers"; - if (run_ssh_command($computer_node_name, $image_identity, $clear_cmd, "root")) { - notify($ERRORS{'DEBUG'}, 0, "cleared $user_name from /etc/sudoers"); - } - else { - notify($ERRORS{'CRITICAL'}, 0, "failed to clear $user_name from /etc/sudoers"); - } - my $sudoers_cmd = "echo \"$user_name ALL= NOPASSWD: ALL\" >> /etc/sudoers"; - if (run_ssh_command($computer_node_name, $image_identity, $sudoers_cmd, "root")) { - notify($ERRORS{'DEBUG'}, 0, "added $user_name to /etc/sudoers"); - } - else { - notify($ERRORS{'CRITICAL'}, 0, "failed to add $user_name to /etc/sudoers"); - } - } ## end if ($imagemeta_rootaccess) - - return 1; } ## end sub reserve @@ -2758,6 +2705,134 @@ sub reboot { #///////////////////////////////////////////////////////////////////////////// +=head2 create_user + + Parameters : username,password,adminoverride(0,1,2),user_uid + Returns : 1 + Description : + +=cut + +sub create_user { + my $self = shift; + if (ref($self) !~ /linux/i) { + notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); + return; + } + + my $management_node_keys = $self->data->get_management_node_keys(); + my $computer_node_name = $self->data->get_computer_node_name(); + my $user_standalone = $self->data->get_user_standalone(); + my $imagemeta_rootaccess = $self->data->get_imagemeta_rootaccess(); + + # Attempt to get the username from the arguments + # If no argument was supplied, use the user specified in the DataStructure + my $user_name = shift; + my $password = shift; + my $adminoverride = shift; + my $user_uid = shift; + + if (!$user_name) { + $user_name = $self->data->get_user_login_id(); + } + if (!$password) { + $password = $self->data->get_reservation_password(); + } + if (!$adminoverride) { + $adminoverride = 0; + } + if (!$user_uid) { + $user_uid = $self->data->get_user_uid(); + } + + #adminoverride, if 0 use value from database for $imagemeta_rootaccess + # if 1 or 2 override database + # 1 - allow admin access, set $imagemeta_rootaccess=1 + # 2 - disallow admin access, set $imagemeta_rootaccess=0 + if ($adminoverride eq '1') { + $imagemeta_rootaccess = 1; + } + elsif ($adminoverride eq '2') { + $imagemeta_rootaccess = 0; + } + else { + #no override detected, do not change database value + } + + my $useradd_string; + if(defined($user_uid) && $user_uid != 0){ + $useradd_string = "/usr/sbin/useradd -u $user_uid -d /home/$user_name -m $user_name -g vcl"; + } + else{ + $useradd_string = "/usr/sbin/useradd -d /home/$user_name -m $user_name -g vcl"; + } + + + my @sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $useradd_string, "root"); + foreach my $l (@{$sshcmd[1]}) { + if ($l =~ /$user_name exists/) { + notify($ERRORS{'OK'}, 0, "detected user already has account"); + if ($self->delete_user()) { + notify($ERRORS{'OK'}, 0, "user has been deleted from $computer_node_name"); + @sshcmd = run_ssh_command($computer_node_name, $management_node_keys, $useradd_string, "root"); + } + } + } + + if ($user_standalone) { + notify($ERRORS{'DEBUG'}, 0, "Standalone user setting single-use password"); + + #Set password + if ($self->changepasswd($computer_node_name, $user_name, $password)) { + notify($ERRORS{'OK'}, 0, "Successfully set password on useracct: $user_name on $computer_node_name"); + } + else { + notify($ERRORS{'CRITICAL'}, 0, "Failed to set password on useracct: $user_name on $computer_node_name"); + return 0; + } + } ## end if ($user_standalone) + + + #Check image profile for allowed root access + if ($imagemeta_rootaccess) { + # Add to sudoers file + #clear user from sudoers file to prevent dups + my $clear_cmd = "sed -i -e \"/^$user_name .*/d\" /etc/sudoers"; + if (run_ssh_command($computer_node_name, $management_node_keys, $clear_cmd, "root")) { + notify($ERRORS{'DEBUG'}, 0, "cleared $user_name from /etc/sudoers"); + } + else { + notify($ERRORS{'CRITICAL'}, 0, "failed to clear $user_name from /etc/sudoers"); + } + my $sudoers_cmd = "echo \"$user_name ALL= NOPASSWD: ALL\" >> /etc/sudoers"; + if (run_ssh_command($computer_node_name, $management_node_keys, $sudoers_cmd, "root")) { + notify($ERRORS{'DEBUG'}, 0, "added $user_name to /etc/sudoers"); + } + else { + notify($ERRORS{'CRITICAL'}, 0, "failed to add $user_name to /etc/sudoers"); + } + } ## end if ($imagemeta_rootaccess) + + return 1; +} ## end sub create_user + +#///////////////////////////////////////////////////////////////////////////// + +=head2 update_server_access + + Parameters : + Returns : + Description : + +=cut + +sub update_server_access { + + +} + +#///////////////////////////////////////////////////////////////////////////// + 1; __END__ Modified: incubator/vcl/trunk/managementnode/lib/VCL/healthcheck.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/healthcheck.pm?rev=1138586&r1=1138585&r2=1138586&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/healthcheck.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/healthcheck.pm Wed Jun 22 19:07:53 2011 @@ -67,6 +67,7 @@ use DBI; #----------GLOBALS-------------- our $LOG = "/var/log/healthcheckvcl.log"; our $MYDBH; +set_logfile_path($LOG); #//////////////////////////////////////////////////////////////////////////////// Modified: incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm?rev=1138586&r1=1138585&r2=1138586&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/reserved.pm Wed Jun 22 19:07:53 2011 @@ -111,6 +111,9 @@ sub process { my $imagemeta_checkuser = $self->data->get_imagemeta_checkuser(); my $reservation_count = $self->data->get_reservation_count(); my $imagemeta_usergroupid = $self->data->get_imagemeta_usergroupid(); + my $server_request_id = $self->data->get_server_request_id(); + my $server_request_admingroupid = $self->data->get_server_request_admingroupid(); + my $server_request_logingroupid = $self->data->get_server_request_logingroupid(); # Update the log table, set the loaded time to now for this request if (update_log_loaded_time($request_logid)) { @@ -228,6 +231,20 @@ sub process { notify($ERRORS{'DEBUG'}, 0, ref($self->os) . "->post_reserve() not implemented by " . ref($self->os)); } + notify($ERRORS{'OK'}, 0, "server_request_id = $server_request_id"); + + #IF server_request_id + if ($server_request_id) { + if($server_request_admingroupid || $server_request_logingroupid ) { + notify($ERRORS{'OK'}, 0, "calling " . ref($self->os) . "::manage_server_access() subroutine"); + if ($self->os->manage_server_access()) { + notify($ERRORS{'DEBUG'}, 0, "Added users to server reservation"); + + } + } + } + + } # close if defined remoteIP elsif ($acknowledge_attempts < 180) { Modified: incubator/vcl/trunk/managementnode/lib/VCL/utils.pm URL: http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1138586&r1=1138585&r2=1138586&view=diff ============================================================================== --- incubator/vcl/trunk/managementnode/lib/VCL/utils.pm (original) +++ incubator/vcl/trunk/managementnode/lib/VCL/utils.pm Wed Jun 22 19:07:53 2011 @@ -136,8 +136,10 @@ our @EXPORT = qw( get_request_by_computerid get_request_end get_request_info + get_reservation_accounts get_resource_groups get_managable_resource_groups + get_user_affiliation get_user_info get_vmhost_info getimagesize @@ -212,6 +214,7 @@ our @EXPORT = qw( update_preload_flag update_request_password update_request_state + update_reservation_accounts update_reservation_lastcheck update_sublog_ipaddress write_currentimage_txt @@ -2276,6 +2279,113 @@ sub is_request_imaging { =head2 get_next_image_default + Parameters : $reservationid + Returns : userid,password,affiliation + Description : Used for server loads, provides list of users for group access + +=cut + +sub get_reservation_accounts { + my ($reservationid) = @_; + my ($calling_package, $calling_filename, $calling_line, $calling_sub) = caller(0); + + if (!defined($reservationid)) { + notify($ERRORS{'WARNING'}, 0, "$calling_sub $calling_package missing mandatory variable: reservationid "); + return 0; + } + + my $select_statement = " + SELECT DISTINCT + reservationaccounts.userid AS reservationaccounts_userid, + reservationaccounts.password AS reservationaccounts_password, + affiliation.name AS affiliation_name + FROM + reservationaccounts, + affiliation, + user + WHERE + user.id = reservationaccounts.userid AND + affiliation.id = user.affiliationid AND + reservationaccounts.reservationid = $reservationid + "; + + # Call the database select subroutine + # This will return an array of one or more rows based on the select statement + my @selected_rows = database_select($select_statement); + + my @ret_array; + my %user_info; + + # Check to make sure 1 or more rows were returned + if (scalar @selected_rows > 0) { + # It contains a hash + for (@selected_rows) { + my %reservation_acct= %{$_}; + my $userid = $reservation_acct{reservationaccounts_userid}; + $user_info{$userid}{"userid"} = $userid; + $user_info{$userid}{"password"} = $reservation_acct{reservationaccounts_password}; + $user_info{$userid}{"affiliation"} = $reservation_acct{affiliation_name}; + } + + return %user_info; + + } + + return (); + +} + +sub update_reservation_accounts { + my $resid = shift; + my $userid = shift; + my $password = shift; + + if ( !$resid ) { + notify($ERRORS{'WARNING'}, 0, "resid argument was not specified"); + return; + } + + if ( !$userid ) { + notify($ERRORS{'WARNING'}, 0, "userid argument was not specified"); + return; + } + + if ( !$password ) { + $password = ''; + } + + my $insert_statement = " + INSERT INTO + reservationaccounts + ( + reservationid, + userid, + password + ) + VALUES + ( + '$resid', + '$userid', + '$password' + ) + "; + + notify($ERRORS{'OK'}, 0, "$insert_statement"); + + if( database_execute($insert_statement) ) { + notify($ERRORS{'OK'}, 0, "inserted new reservationaccount info $resid $userid"); + return 1; + } + else { + return 0; + notify($ERRORS{'OK'}, 0, "failed to insert new reservationaccount info $resid $userid"); + } +} + +#///////////////////////////////////////////////////////////////////////////// + +=head2 get_next_image_default + Parameters : $computerid Returns : imageid,imagerevisionid,imagename Description : Looks for any upcoming reservations @@ -4427,12 +4537,12 @@ sub get_request_info { elsif ($key =~ /computerprovisioningmodule_/) { $request_info{reservation}{$reservation_id}{computer}{provisioning}{module}{$original_key} = $value; } - elsif ($key =~ /serverrequest_/) { - $request_info{reservation}{$reservation_id}{$original_key} = $value; - } else { notify($ERRORS{'WARNING'}, 0, "unknown key found in SQL data: $key"); } + if ($key =~ /serverrequest_/) { + $request_info{reservation}{$reservation_id}{serverrequest}{$original_key} = $value; + } } # Close foreach key in reservation row } # Close loop through selected rows @@ -4523,7 +4633,7 @@ sub get_request_info { # Loop through all the reservations foreach my $reservation_id (keys %{$request_info{reservation}}) { - + # Set server request NULL values to 0 if (defined($request_info{reservation}{$reservation_id}{serverrequest}{id})) { @@ -7961,6 +8071,63 @@ EOF #///////////////////////////////////////////////////////////////////////////// +=head2 get_user_affiliation + + Parameters : $user_id + Returns : scalar - affiliation name + Description : + +=cut + +sub get_user_affiliation { + my ($user_id) = shift; + + if(!defined($user_id)){ + notify($ERRORS{'WARNING'}, $LOGFILE, "user_id was not supplied"); + return 0; + } + + my $select_statement = <<EOF; +SELECT DISTINCT +affiliation.name +FROM +user, +affiliation +WHERE +affiliation.id = user.affiliationid AND +user.id = $user_id +EOF + +# Call the database select subroutine + # This will return an array of one or more rows based on the select statement + my @selected_rows = database_select($select_statement); + + # Check to make sure 1 row was returned + if (scalar @selected_rows == 0) { + notify($ERRORS{'WARNING'}, 0, "zero rows were returned from database select"); + return (); + } + elsif (scalar @selected_rows > 1) { + notify($ERRORS{'WARNING'}, 0, "" . scalar @selected_rows . " rows were returned from database select"); + return (); + } + + # Get the single returned row + # It contains a hash + + # Make sure we return undef if the column wasn't found + if (defined $selected_rows[0]{name}) { + my $name = $selected_rows[0]{name}; + return $name; + } + else { + return undef; + } + +} + +#///////////////////////////////////////////////////////////////////////////// + =head2 get_group_name Parameters : $group_id