xdsh -K support (still need to do hierarchy)
This commit is contained in:
		| @@ -35,7 +35,7 @@ package xCAT::RemoteShellExp; | ||||
|                   node. | ||||
|    DSH_TO_USERID - The userid on the node where the ssh keys will be updated. | ||||
|    DSH_ENABLE_SSH - Node to node root passwordless ssh will be setup. | ||||
|   | ||||
|    DSH_ZONE_SSHKEYS  - directory containing the zones root .ssh keys  | ||||
|  | ||||
|  Usage: remoteshellexp | ||||
|    [-t node list]  test ssh connection to the node  | ||||
| @@ -144,7 +144,7 @@ sub remoteshellexp | ||||
|   } else { | ||||
|      $from_userid="root"; | ||||
|   } | ||||
|   # set User on the node where we will send the keys  | ||||
|   # set User  on the node where we will send the keys  | ||||
|   # this id can be a local id as well as root  | ||||
|   if ($ENV{'DSH_TO_USERID'}) { | ||||
|      $to_userid=$ENV{'DSH_TO_USERID'}; | ||||
| @@ -154,18 +154,19 @@ sub remoteshellexp | ||||
|   # set User home directory to find the ssh public key to send  | ||||
|   # For non-root ids information may not be in /etc/passwd | ||||
|   #  but elsewhere like LDAP  | ||||
|     | ||||
|   if ($ENV{'DSH_FROM_USERID_HOME'}) { | ||||
|      $home=$ENV{'DSH_FROM_USERID_HOME'}; | ||||
|        $home=$ENV{'DSH_FROM_USERID_HOME'}; | ||||
|   } else { | ||||
|      $home=xCAT::Utils->getHomeDir($from_userid); | ||||
|       $home=xCAT::Utils->getHomeDir($from_userid); | ||||
|   } | ||||
|    | ||||
|   # This indicates we will generate new ssh keys for the user, | ||||
|   # if they are not already there | ||||
|   my $key="$home/.ssh/id_rsa"; | ||||
|   my $key2="$home/.ssh/id_rsa.pub"; | ||||
|   # Check to see if empty | ||||
|   if (-z $key) { | ||||
|   # unless using zones | ||||
|    my $key="$home/.ssh/id_rsa"; | ||||
|    my $key2="$home/.ssh/id_rsa.pub"; | ||||
|    # Check to see if empty | ||||
|    if (-z $key) { | ||||
|          my $rsp = {}; | ||||
|          $rsp->{error}->[0] =  | ||||
|          "The $key file is empty. Remove it and rerun the command."; | ||||
| @@ -183,8 +184,7 @@ sub remoteshellexp | ||||
|   }  | ||||
|   if (($flag eq "k") && (!(-e $key)))  | ||||
|   { | ||||
|      # if the file size of the id_rsa key is 0, tell them to remove it | ||||
|      # and run the command again | ||||
|      # updating keys and the key file does not exist  | ||||
|      $rc=xCAT::RemoteShellExp->gensshkeys($expecttimeout); | ||||
|   } | ||||
|   # send ssh keys to the nodes/devices, to setup passwordless ssh  | ||||
| @@ -200,6 +200,9 @@ sub remoteshellexp | ||||
|     if ($ssh_setup_cmd) { # setup ssh on devices | ||||
|      $rc=xCAT::RemoteShellExp->senddeviceskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$ssh_setup_cmd,$nodes, $expecttimeout); | ||||
|     } else {  #setup ssh on nodes | ||||
|      if ($ENV{'DSH_ZONE_SSHKEYS'}) {   # if using zones the override the location of the keys | ||||
|         $home= $ENV{'DSH_ZONE_SSHKEYS'}; | ||||
|      }   | ||||
|      $rc=xCAT::RemoteShellExp->sendnodeskeys($remoteshell,$remotecopy,$to_userid,$to_user_password,$home,$nodes, $expecttimeout); | ||||
|     }  | ||||
|   } | ||||
| @@ -496,11 +499,14 @@ sub sendnodeskeys | ||||
|     #  copy to the node to the temp directory  | ||||
|     #  scp $HOME/.ssh/tmp/authorized_keys to_userid@<node>:/tmp/$to_userid/.ssh | ||||
|     #  scp $HOME/.ssh/id_rsa.pub to_userid@<node>:/tmp/$to_userid/.ssh | ||||
|     #  Note if using zones,  the keys do not come from ~/.ssh but from the | ||||
|     #  zone table, sshkeydir attribute.  For zones the userid is always root | ||||
|     #  If you are going to enable ssh to ssh between nodes, then | ||||
|     #  scp $HOME/.ssh/id_rsa to that temp directory on the node | ||||
|     #  copy the script $HOME/.ssh/copy.sh to the node, it will do the  | ||||
|     #  the work of setting up the user's ssh keys  and clean up | ||||
|     #  ssh (run)  copy.sh on the node | ||||
|      | ||||
|     my @nodelist=split(/,/,$nodes); | ||||
|     foreach my $node (@nodelist) { | ||||
|       $sendkeys = new Expect; | ||||
|   | ||||
| @@ -427,23 +427,28 @@ rmdir \"/tmp/$to_userid\" \n"; | ||||
|     if (($from_userid eq "root") && (!($ENV{'DEVICETYPE'}))) { | ||||
|       # Need to check if nodes are in a zone.   | ||||
|       my @zones; | ||||
|       my $tab = xCAT::Table->new("zone");   | ||||
|       my $tab = xCAT::Table->new("zone");  | ||||
|       my @zones;  | ||||
|       if ($tab)  | ||||
|       { | ||||
|           # if we have zones, need to send the zone keys to each node in the zone | ||||
|           my @zones = $tab->getAllAttribs('zonename'); | ||||
|           my @attribs = ("zonename"); | ||||
|           @zones = $tab->getAllAttribs(@attribs); | ||||
|           $tab->close(); | ||||
|       } else { | ||||
|          $rsp->{data}->[0] = "Could not open zone table.\n"; | ||||
|          xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); | ||||
|          return 1; | ||||
|       } | ||||
|       # check for zones,  key send is different if zones defined or not | ||||
|        | ||||
|       if (@zones) {  # we have zones defined | ||||
|          my $rc = xCAT::TableUtils->sendkeysTOzones($ref_nodes,$expecttimeout); | ||||
|          if ($rc != 0) | ||||
|          {    | ||||
|                 $rsp->{data}->[0] = "Error sending ssh keys to the zones.\n"; | ||||
|                 xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); | ||||
|                 exit 1; | ||||
|  | ||||
|          } | ||||
|       } else { # no zones | ||||
| @@ -614,26 +619,117 @@ sub sendkeysNOzones | ||||
| #-------------------------------------------------------------------------------- | ||||
| sub sendkeysTOzones  | ||||
| { | ||||
|     my ($class, $ref_nodes,$expecttimeout) = @_; | ||||
|       my ($class, $ref_nodes,$expecttimeout) = @_; | ||||
|       my @nodes=$ref_nodes; | ||||
|       my $n_str    = $nodes[0]; | ||||
|       my @nodelist=  split(",", $n_str); | ||||
|       my %zonehash =xCAT::Zone->getNodeZones(@nodelist); | ||||
|        # for each zone in the zonehash | ||||
|        #   if sshbetweennodes is yes | ||||
|        #     $ENV{'DSH_ENABLE_SSH'} = "YES"; | ||||
|        #   else  | ||||
|        #     unset $ENV{'DSH_ENABLE_SSH'} | ||||
|        # send the keys to the nodes | ||||
|        #  my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh",$nodelist,$expecttimeout); | ||||
|        # if ($rc != 0) | ||||
|        # { | ||||
|        #  $rsp->{data}->[0] = "remoteshellexp failed sending keys to $zonename."; | ||||
|        #  xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); | ||||
|        # | ||||
|        #  } | ||||
|        # } # endforeach | ||||
|     return 0; | ||||
|       my @nodes=  split(",", $n_str); | ||||
|       my $rsp = (); | ||||
|       my $cmd; | ||||
|       my $roothome = xCAT::Utils->getHomeDir("root"); | ||||
|       my $zonehash =xCAT::Zone->getzoneinfo($::CALLBACK,\@nodes); | ||||
|       foreach my $zonename (keys %$zonehash) { | ||||
|         # build list of nodes | ||||
|         my $zonenodelist=""; | ||||
|         foreach my $node (@{$zonehash->{$zonename}->{nodes}}) { | ||||
|           $zonenodelist .= $node; | ||||
|           $zonenodelist .= ","; | ||||
|                 | ||||
|         } | ||||
|         $zonenodelist =~ s/,$//;   # remove last comma | ||||
|         # if any nodes defined for the zone | ||||
|         if ($zonenodelist) { | ||||
|           # check to see if we enable passwordless ssh between the nodes | ||||
|           if (!(defined($zonehash->{$zonename}->{sshbetweennodes}))||  | ||||
|             (($zonehash->{$zonename}->{sshbetweennodes} =~ /^yes$/i ) | ||||
|              || ($zonehash->{$zonename}->{sshbetweennodes} eq "1"))) { | ||||
|   | ||||
|              $ENV{'DSH_ENABLE_SSH'} = "YES"; | ||||
|           } else {  | ||||
|              delete $ENV{'DSH_ENABLE_SSH'};  # do not enable passwordless ssh | ||||
|           } | ||||
|           # point to the ssh keys to send for this zone | ||||
|           my $keydir = $zonehash->{$zonename}->{sshkeydir} ; | ||||
|  | ||||
|           # check to see if the id_rsa and id_rsa.pub key is in the directory | ||||
|           my $key="$keydir/id_rsa"; | ||||
|           my $key2="$keydir/id_rsa.pub"; | ||||
|           # Check to see if empty | ||||
|           if (!(-e $key)) { | ||||
|             my $rsp = {}; | ||||
|              $rsp->{error}->[0] = | ||||
|             "The $key file does not exist for $zonename. Need to use chzone to regenerate the keys."; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); | ||||
|             return 1; | ||||
|           } | ||||
|           if (!(-e $key2)) { | ||||
|              my $rsp = {}; | ||||
|              $rsp->{error}->[0] = | ||||
|              "The $key2 file does not exist for $zonename. Need to use chzone to regenerate the keys."; | ||||
|              xCAT::MsgUtils->message("E", $rsp, $::CALLBACK, 1); | ||||
|              return 1; | ||||
|  | ||||
|           } | ||||
|            | ||||
|           # now put copy.sh in the zone directory from ~/.ssh | ||||
|           my $rootkeydir="$roothome/.ssh"; | ||||
|           if ($rootkeydir ne $keydir) {  # the zone keydir is not the same as ~/.ssh.   | ||||
|             $cmd="cp $rootkeydir/copy.sh $keydir"; | ||||
|             xCAT::Utils->runcmd($cmd, 0); | ||||
|             if ($::RUNCMD_RC != 0) | ||||
|             { | ||||
|                my $rsp = {}; | ||||
|                $rsp->{error}->[0] = | ||||
|                "Could not copy copy.sh to the zone key dir"; | ||||
|                xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); | ||||
|                return 1; | ||||
|             } | ||||
|           } | ||||
|           # Also create  $keydir/tmp and put root's id_rsa.pub (in authorized_keys) for the transfer | ||||
|           $cmd="mkdir -p $keydir/tmp"; | ||||
|           xCAT::Utils->runcmd($cmd, 0); | ||||
|           if ($::RUNCMD_RC != 0) | ||||
|           { | ||||
|              my $rsp = {}; | ||||
|              $rsp->{error}->[0] = | ||||
|              "Could not mkdir the zone $keydir/tmp"; | ||||
|              xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); | ||||
|              return 1; | ||||
|           } | ||||
|           # create authorized_keys file  | ||||
|           if (xCAT::Utils->isMN()) {    # if on Management Node | ||||
|              $cmd = " cp $roothome/.ssh/id_rsa.pub $keydir/tmp/authorized_keys"; | ||||
|           } else {  # SN | ||||
|              $cmd = " cp $roothome/.ssh/authorized_keys $keydir/tmp/authorized_keys"; | ||||
|           } | ||||
|           xCAT::Utils->runcmd($cmd, 0); | ||||
|           if ($::RUNCMD_RC != 0) | ||||
|           { | ||||
|             $rsp->{data}->[0] = "$cmd failed.\n"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); | ||||
|             return (1); | ||||
|           } | ||||
|           else | ||||
|           { | ||||
|              chmod 0600, "$keydir/.ssh/tmp/authorized_keys"; | ||||
|           } | ||||
|           # strip off .ssh | ||||
|           my ($newkeydir,$ssh) = (split(/\.ssh/, $keydir)); | ||||
|           $ENV{'DSH_ZONE_SSHKEYS'} =$newkeydir ; | ||||
|           # send the keys to the nodes | ||||
|            my $rc=xCAT::RemoteShellExp->remoteshellexp("s",$::CALLBACK,"/usr/bin/ssh", | ||||
|            $zonenodelist,$expecttimeout); | ||||
|            if ($rc != 0) | ||||
|            { | ||||
|              $rsp = {}; | ||||
|              $rsp->{data}->[0] = "remoteshellexp failed sending keys to $zonename."; | ||||
|              xCAT::MsgUtils->message("E", $rsp, $::CALLBACK); | ||||
|  | ||||
|            } | ||||
|         } # end nodes in the zone | ||||
|            | ||||
|        }  # end for each zone | ||||
|  | ||||
|     return (0); | ||||
| } | ||||
| #-------------------------------------------------------------------------------- | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,7 @@ This program module file, is a set of Zone utilities used by xCAT *zone commands | ||||
| =cut | ||||
|  | ||||
| #-------------------------------------------------------------------------------- | ||||
| sub  genSSHRootKeys  | ||||
| sub genSSHRootKeys  | ||||
| { | ||||
|     my ($class, $callback, $keydir,$zonename,$rsakey) = @_; | ||||
|      | ||||
| @@ -71,22 +71,6 @@ sub  genSSHRootKeys | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     # | ||||
|     #  create /install/postscripts/_ssh/zonename if needed | ||||
|     # | ||||
|     my $installdir = xCAT::TableUtils->getInstallDir();  # get installdir | ||||
|     if (!-d "$installdir/postscripts/_ssh/$zonename") | ||||
|     { | ||||
|         my $cmd = "/bin/mkdir -m 755 -p $installdir/postscripts/_ssh/$zonename"; | ||||
|         my $output = xCAT::Utils->runcmd("$cmd", 0); | ||||
|         if ($::RUNCMD_RC != 0) | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{error}->[0] = "Could not create $installdir/postscripts/_ssh/$zonename directory."; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback); | ||||
|            return 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     #need to gen a new rsa key for root for the zone  | ||||
|     my $pubfile = "$keydir/id_rsa.pub"; | ||||
| @@ -152,29 +136,6 @@ sub  genSSHRootKeys | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback); | ||||
|             return 1; | ||||
|     } | ||||
|     # copy authorized_keys for install on node | ||||
|     if (-r $pubfile) | ||||
|     { | ||||
|         my $cmd = | ||||
|           "/bin/cp -p $pubfile $installdir/postscripts/_ssh/$zonename "; | ||||
|         my $output = xCAT::Utils->runcmd("$cmd", 0); | ||||
|         if ($::RUNCMD_RC != 0) | ||||
|         { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{error}->[0] =  | ||||
|            "Could not copy $pubfile to $installdir/postscripts/_ssh/$zonename"; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback); | ||||
|             return 1; | ||||
|  | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|             my $rsp = {}; | ||||
|             $rsp->{error}->[0] =  | ||||
|            "Could not copy $pubfile to $installdir/postscripts/_ssh/$zonename, because $pubfile does not exist."; | ||||
|             xCAT::MsgUtils->message("E", $rsp, $callback); | ||||
|     } | ||||
| } | ||||
| #-------------------------------------------------------------------------------- | ||||
|  | ||||
| @@ -188,7 +149,7 @@ sub  genSSHRootKeys | ||||
| =cut | ||||
|  | ||||
| #-------------------------------------------------------------------------------- | ||||
| sub  getdefaultzone  | ||||
| sub getdefaultzone  | ||||
| { | ||||
|  my ($class, $callback) = @_; | ||||
|  my $defaultzone; | ||||
| @@ -262,7 +223,7 @@ sub iszonedefined | ||||
| =cut | ||||
|  | ||||
| #-------------------------------------------------------------------------------- | ||||
| sub  getzoneinfo  | ||||
| sub getzoneinfo  | ||||
| { | ||||
|   my ($class, $callback,$nodes) = @_; | ||||
|  $::GETZONEINFO_RC=0;  | ||||
| @@ -279,6 +240,7 @@ sub  getzoneinfo | ||||
|           my $zonename=$zone->{zonename}; | ||||
|           $zonehash->{$zonename}->{sshkeydir}= $zone->{sshkeydir}; | ||||
|           $zonehash->{$zonename}->{defaultzone}= $zone->{defaultzone}; | ||||
|           $zonehash->{$zonename}->{sshbetweennodes}= $zone->{sshbetweennodes}; | ||||
|           # find the defaultzone | ||||
|           if ((defined($zone->{defaultzone})) && | ||||
|           (($zone->{defaultzone} =~ /^yes$/i )  | ||||
| @@ -299,44 +261,40 @@ sub  getzoneinfo | ||||
|  my $nodelisttab = xCAT::Table->new("nodelist"); | ||||
|  my $nodehash = $nodelisttab->getNodesAttribs(\@$nodes, ['zonename']);  | ||||
|  # for each of the nodes, look up it's zone name and assign to the zonehash | ||||
|  # if the node is a service node, it is assigned to the __xcatzone which gets its keys from | ||||
|  #    the ~/.ssh dir no matter what in the database for the zonename.  | ||||
|  # If the nodes nodelist.zonename attribute is a zonename, it is assigned to that zone | ||||
|  # If the nodes nodelist.zonename attribute is undefined: | ||||
|  #         If there is a defaultzone in the zone table, the node is assigned to that zone | ||||
|  #         If there is no defaultzone in the zone table, the node is assigned to the ~.ssh keydir | ||||
|  #         If there is no defaultzone error out  | ||||
|   | ||||
|  | ||||
|  my @allSN=xCAT::ServiceNodeUtils->getAllSN("ALL");  # read all the servicenodes define  | ||||
|  my $xcatzone = "__xcatzone";  # if node is in no zones or a service node, use this one | ||||
|  $zonehash->{$xcatzone}->{sshkeydir}= "~/.ssh";  | ||||
|  foreach my $node (@$nodes) { | ||||
|     my $zonename; | ||||
|     if (grep(/^$node$/, @allSN)) {  # this is a servicenode, treat special | ||||
|       $zonename=$xcatzone;    # always use ~/.ssh directory | ||||
|     } else { # use the nodelist.zonename attribute | ||||
|       $zonename=$nodehash->{$node}->[0]->{zonename}; | ||||
|     } | ||||
|     $zonename=$nodehash->{$node}->[0]->{zonename}; | ||||
|     if (defined($zonename)) {  # zonename explicitly defined in nodelist.zonename | ||||
|        # check to see if defined in the zone table | ||||
|        if (!(grep(/^$zonename$/, @zones))) { | ||||
|      # check to see if defined in the zone table | ||||
|      unless ( xCAT::Zone->iszonedefined($zonename)) { | ||||
|           my $rsp = {}; | ||||
|           $rsp->{error}->[0] =  | ||||
|          "$node has a  zonenane: $zonename that is  not define in the zone table. Remove the zonename from the node, or create the zone using mkzone."; | ||||
|           xCAT::MsgUtils->message("E", $rsp, $callback); | ||||
|           $::GETZONEINFO_RC =1; | ||||
|           return; | ||||
|        } | ||||
|        push @{$zonehash->{$zonename}->{nodes}},$node; | ||||
|       } | ||||
|       push @{$zonehash->{$zonename}->{nodes}},$node; | ||||
|     } else { # no explict zonename | ||||
|       if (defined ($defaultzone)) {  # there is a default zone in the zone table, use it | ||||
|        push @{$zonehash->{$defaultzone}->{nodes}},$node; | ||||
|       } else {  # if no default then use the ~/.ssh keys as the default, put them in the __xcatzone | ||||
|           push @{$zonehash->{$xcatzone}->{nodes}},$node; | ||||
|       } else {  # if no default, this is an error | ||||
|           my $rsp = {}; | ||||
|           $rsp->{error}->[0] =  | ||||
|          "There is no default zone defined in the zone table. There must be exactly one default zone. "; | ||||
|           xCAT::MsgUtils->message("E", $rsp, $callback); | ||||
|           $::GETZONEINFO_RC =1; | ||||
|           return; | ||||
|         | ||||
|       }    | ||||
|     }    | ||||
|  } | ||||
|  return; | ||||
|  return $zonehash; | ||||
| } | ||||
| 1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user