mirror of
				https://github.com/xcat2/xcat-core.git
				synced 2025-10-31 03:12:30 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1012 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1012 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head1
 | |
|   xCAT plugin package to handle mkzone,chzone,Input rmzone commands
 | |
| 
 | |
|    Supported command:
 | |
|          mkzone,chzone,rmzone - manage xcat cluster zones
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| package xCAT_plugin::zone;
 | |
| 
 | |
| BEGIN
 | |
| {
 | |
|     $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : -d '/opt/xcat' ? '/opt/xcat' : '/usr';
 | |
| }
 | |
| 
 | |
| use strict;
 | |
| require xCAT::Utils;
 | |
| require xCAT::Zone;
 | |
| require xCAT::MsgUtils;
 | |
| require xCAT::Table;
 | |
| use xCAT::NodeRange;
 | |
| use xCAT::NodeRange qw/noderange abbreviate_noderange/;
 | |
| 
 | |
| use Getopt::Long;
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3  handled_commands
 | |
| 
 | |
| Return list of commands handled by this plugin
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| sub handled_commands
 | |
| {
 | |
|     return { mkzone => "zone",
 | |
|         chzone => "zone",
 | |
|         rmzone => "zone",
 | |
|     };
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3  process_request
 | |
| 
 | |
|   Process the command, this only runs on the management node
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub process_request
 | |
| {
 | |
| 
 | |
|     my $request  = shift;
 | |
|     my $callback = shift;
 | |
|     my $sub_req  = shift;
 | |
|     $::CALLBACK = $callback;
 | |
|     my $command = $request->{command}->[0];
 | |
|     my $rc      = 0;
 | |
| 
 | |
|     # the directory which will contain the zone keys
 | |
|     my $keydir = "/etc/xcat/sshkeys/";
 | |
| 
 | |
|     # check if Management Node, if not error
 | |
|     unless (xCAT::Utils->isMN())
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] = "The $command may only be run on the Management Node.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback, 1);
 | |
|         return 1;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     # you may not run on AIX
 | |
|     if (xCAT::Utils->isAIX()) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] = "The $command may only be run on a Linux Cluster.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback, 1);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # test to see if any parms
 | |
|     if (scalar($request->{arg} == 0)) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
| "No parameters input to the $command command,  see man page for syntax.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         exit 1;
 | |
|     }
 | |
| 
 | |
|     my $args = $request->{arg};
 | |
|     @ARGV = @{$args};    # get arguments
 | |
|                          # Get the zonename if it is in the input
 | |
|     my @SaveARGV = @ARGV;
 | |
|     my $zonename;
 | |
|     my $arg = @SaveARGV[0];
 | |
|     if (!($arg =~ /-h/) && (!($arg =~ /-v/))) { # if not -h -v,then it must be a zone name
 | |
|         $zonename = @SaveARGV[0];    # here is the zonename, if there is one
 | |
|         if ($zonename) { #  take zonename off the argument list so it will parse correctly
 | |
|             my $tmp = shift(@SaveARGV);
 | |
|             @ARGV = @SaveARGV;
 | |
|         }
 | |
|     }
 | |
|     Getopt::Long::Configure("posix_default");
 | |
|     Getopt::Long::Configure("no_gnu_compat");
 | |
|     Getopt::Long::Configure("bundling");
 | |
|     my %options = ();
 | |
| 
 | |
|     if (
 | |
|         !GetOptions(
 | |
|             'a|noderange=s'           => \$options{'addnoderange'},
 | |
|             'r|noderange=s'           => \$options{'rmnoderange'},
 | |
|             'defaultzone|defaultzone' => \$options{'defaultzone'},
 | |
|             'g|assigngrp'             => \$options{'assigngroup'},
 | |
|             'f|force'                 => \$options{'force'},
 | |
|             'h|help'                  => \$options{'help'},
 | |
|             'k|sshkeypath=s'          => \$options{'sshkeypath'},
 | |
|             'K|genkeys'               => \$options{'gensshkeys'},
 | |
|             's|sshbetweennodes=s'     => \$options{'sshbetweennodes'},
 | |
|             'v|version'               => \$options{'version'},
 | |
|             'V|verbose'               => \$options{'verbose'},
 | |
|         )
 | |
|       )
 | |
|     {
 | |
| 
 | |
|         &usage($callback, $command);
 | |
|         exit 1;
 | |
|     }
 | |
| 
 | |
|     # if the ARGS still have data we have invalid input
 | |
|     if (@ARGV) {
 | |
|         my $args = join(',', @ARGV);
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
| "The input to the command: $command contained invalid arguments: $args.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback, 1);
 | |
|         exit 1;
 | |
|     }
 | |
| 
 | |
|     if ($options{'help'})
 | |
|     {
 | |
|         &usage($callback, $command);
 | |
|         exit 0;
 | |
|     }
 | |
|     if ($options{'version'})
 | |
|     {
 | |
|         my $version = xCAT::Utils->Version();
 | |
|         my $rsp     = {};
 | |
|         $rsp->{data}->[0] = $version;
 | |
|         xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|         exit 0;
 | |
|     }
 | |
| 
 | |
|     # test to see if the zonename was input
 | |
|     if (!$zonename) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           "zonename not specified, it is required for this command.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         exit 1;
 | |
|     } else {
 | |
|         $request->{zonename} = $zonename;
 | |
|     }
 | |
| 
 | |
|     # if -s entered must be yes/1 or no/0
 | |
|     if ($options{'sshbetweennodes'}) {
 | |
|         if ($options{'sshbetweennodes'} =~ /^yes$/i || $options{'sshbetweennodes'} eq "1") {
 | |
|             $options{'sshbetweennodes'} = "yes";
 | |
|         } else {
 | |
|             if ($options{'sshbetweennodes'} =~ /^no$/i || $options{'sshbetweennodes'} eq "0") {
 | |
|                 $options{'sshbetweennodes'} = "no";
 | |
|             } else {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{error}->[0] =
 | |
| "The input on the -s flag $options{'sshbetweennodes'} is not valid.";
 | |
|                 xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|                 exit 1;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # cannot enter -K and -k
 | |
|     if (($options{'sshkeypath'}) && ($options{'gensshkeys'})) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           "The input of -k and -K is not valid on the command : $command.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         exit 1;
 | |
|     }
 | |
| 
 | |
|     # check for site.sshbetweennodes attribute, put out a warning it will not be used as long
 | |
|     # as zones are defined in the zone table.
 | |
|     my @entries = xCAT::TableUtils->get_site_attribute("sshbetweennodes");
 | |
|     if ($entries[0]) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{info}->[0] =
 | |
| "The site table sshbetweennodes attribute is set to $entries[0].  It is not used when zones are defined.  To get rid of this warning, remove the site table sshbetweennodes attribute.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|     }
 | |
| 
 | |
|     #  -a and -r flags cannot be used together
 | |
|     if (($options{'addnoderange'}) && ($options{'rmnoderange'})) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
| "You may not use the -a flag to add nodes and the -r flag to remove nodes on one command.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         exit 1;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     # save input noderange  to add nodes
 | |
|     if ($options{'addnoderange'}) {
 | |
| 
 | |
|         # check to see if Management Node is in the noderange, if so error
 | |
|         $request->{noderange}->[0] = $options{'addnoderange'};
 | |
|         my @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]);
 | |
|         my @mname = xCAT::Utils->noderangecontainsMn(@nodes);
 | |
|         if (@mname)
 | |
|         {    # MN in the nodelist
 | |
|             my $nodes = join(',', @mname);
 | |
|             my $rsp = {};
 | |
|             $rsp->{error}->[0] =
 | |
| "You must not run $command and include the  management node: $nodes.";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1);
 | |
|             exit 1;
 | |
|         }
 | |
| 
 | |
| 
 | |
|     }
 | |
| 
 | |
|     # save input noderange  to remove nodes
 | |
|     if ($options{'rmnoderange'}) {
 | |
| 
 | |
|         # check to see if Management Node is in the noderange, if so error
 | |
|         $request->{noderange}->[0] = $options{'rmnoderange'};
 | |
|         my @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]);
 | |
|         my @mname = xCAT::Utils->noderangecontainsMn(@nodes);
 | |
|         if (@mname)
 | |
|         {    # MN in the nodelist
 | |
|             my $nodes = join(',', @mname);
 | |
|             my $rsp = {};
 | |
|             $rsp->{error}->[0] =
 | |
| "You must not run $command and include the  management node: $nodes.";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $callback, 1);
 | |
|             exit 1;
 | |
|         }
 | |
| 
 | |
| 
 | |
|     }
 | |
|     if ($options{'verbose'})
 | |
|     {
 | |
|         $::VERBOSE = "yes";
 | |
|     }
 | |
| 
 | |
|     if ($command eq "mkzone")
 | |
|     {
 | |
|         $rc = mkzone($request, $callback, \%options, $keydir);
 | |
|     }
 | |
|     if ($command eq "chzone")
 | |
|     {
 | |
|         $rc = chzone($request, $callback, \%options, $keydir);
 | |
|     }
 | |
|     if ($command eq "rmzone")
 | |
|     {
 | |
|         $rc = rmzone($request, $callback, \%options);
 | |
|     }
 | |
|     my $rsp = {};
 | |
|     if ($rc == 0) {
 | |
|         $rsp->{info}->[0] = "The $command ran successfully.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|     } else {
 | |
|         $rsp->{error}->[0] = "The $command had errors.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|     }
 | |
|     return $rc;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
| 
 | |
|    Parses and runs  mkzone
 | |
|    Input
 | |
|      request
 | |
|      callback
 | |
|      Input  arguments from the GetOpts
 | |
|      zone ssh key dir
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub mkzone
 | |
| {
 | |
|     my ($request, $callback, $options, $keydir) = @_;
 | |
|     my $rc = 0;
 | |
| 
 | |
|     # already checked but lets do it again,  need a zonename, it is the only required parm
 | |
|     if (!($request->{zonename})) {
 | |
| 
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           "zonename not specified The zonename is required.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # test for -g, if no noderange this is an error
 | |
|     if ((!defined($$options{'addnoderange'})) && ($$options{'assigngroup'})) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " The -g flag requires a noderange ( -a).";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # test for -r,  not valid
 | |
|     if ($$options{'rmnoderange'}) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " The -r flag Is not valid for mkzone. Use chzone.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # check to see if the input zone already exists
 | |
|     if (xCAT::Zone->iszonedefined($request->{zonename})) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
| " zonename: $request->{zonename} already defined, use chzone or rmzone to change or remove it.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # Create path to generated ssh keys
 | |
|     # keydir comes in set to /etc/xcat/sshkeys
 | |
|     $keydir .= $request->{zonename};
 | |
|     $keydir .= "/.ssh";
 | |
| 
 | |
| 
 | |
|     # add new zones to the zone table
 | |
|     $rc = addtozonetable($request, $callback, $options, $keydir);
 | |
|     if ($rc == 0) {    # zone table setup is ok
 | |
|                        # test for a noderange, if(-a) not supplied nothing to do
 | |
|         if (defined($$options{'addnoderange'})) {
 | |
|             $rc = addnodestozone($request, $callback, $options, $keydir);
 | |
|         }
 | |
|         if ($rc == 0) {    # zone table setup is ok
 | |
|                            # generate root ssh keys
 | |
|             $rc = gensshkeys($request, $callback, $options, $keydir);
 | |
|             if ($rc != 0) {
 | |
|                 return 1;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return $rc;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
| 
 | |
|    Parses and runs chzone
 | |
|    Input
 | |
|      request
 | |
|      callback
 | |
|      Input  arguments from the GetOpts
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub chzone
 | |
| {
 | |
|     my ($request, $callback, $options, $keydir) = @_;
 | |
|     my $rc = 0;
 | |
| 
 | |
|     # Create default  path to generated ssh keys
 | |
|     # keydir comes in set to /etc/xcat/sshkeys
 | |
|     $keydir .= $request->{zonename};
 | |
|     $keydir .= "/.ssh";
 | |
|     my $zonename = $request->{zonename};
 | |
| 
 | |
|     # already checked but lets do it again,  need a zonename
 | |
|     if (!($request->{zonename})) {
 | |
| 
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           "zonename not specified The zonename is required.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # see if they asked to do anything
 | |
|     if ((!($$options{'sshkeypath'})) && (!($$options{'gensshkeys'})) &&
 | |
|         (!($$options{'addnoderange'})) && (!($$options{'rmnoderange'})) &&
 | |
|         (!($$options{'defaultzone'}))  &&
 | |
|         (!($$options{'assigngroup'}))  && (!($$options{'sshbetweennodes'}))) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{info}->[0] =
 | |
|           "chzone was run but nothing to do.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     # test for -g, if no noderange (-r or -a) this is an error
 | |
|     if (((!defined($$options{'addnoderange'})) && (!defined($$options{'rmnoderange'}))) && ($$options{'assigngroup'})) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " The -g flag requires a noderange using the -a or -r option.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     #  if -r remove nodes from zone, check to see that they are a member of the zone
 | |
|     #  if not a member of the zone,  error out and do nothing
 | |
|     if ($$options{'rmnoderange'}) {
 | |
|         my @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]);
 | |
| 
 | |
|         foreach my $node (@nodes) {
 | |
|             my $nodezonename = xCAT::Zone->getmyzonename($node);
 | |
|             if ($nodezonename ne $zonename) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{error}->[0] =
 | |
| " $node does not belong to the zone:$zonename. Rerun the chzone -r  command with only nodes in the noderange that are currently assigned to the zone.";
 | |
|                 xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|                 return 1;
 | |
|             }
 | |
| 
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # get the zone ssh key directory. We don't have a good zone without it.
 | |
|     my $sshrootkeydir = xCAT::Zone->getzonekeydir($zonename);
 | |
|     if ($sshrootkeydir == 1) {    # error return
 | |
|             #if we have been requested to regenerated the ssh keys continue
 | |
|         if (($$options{'sshkeypath'}) || ($$options{'gensshkeys'})) {
 | |
|             my $rsp = {};
 | |
|             $rsp->{info}->[0] =
 | |
| " sshkeydir attribute not defined for $zonename. The zone sshkeydir will be regenerated.";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|         } else { # sshkeydir is missing  and they did not request to regenerate,   that is an error
 | |
|             my $rsp = {};
 | |
|             $rsp->{error}->[0] =
 | |
| " sshkeydir attribute not defined for $zonename. The zone sshkeydir must be regenerated. Rerun this command with -k or -K options";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|             return 1;
 | |
|         }
 | |
|     } else {    # we got a sshkeydir from the database, use it
 | |
|         $keydir = $sshrootkeydir;
 | |
|     }
 | |
| 
 | |
|     # do we regenerate keys (-k or -K)
 | |
|     if (($$options{'sshkeypath'}) || ($$options{'gensshkeys'})) {
 | |
|         $rc = gensshkeys($request, $callback, $options, $keydir);
 | |
|         if ($rc != 0) {
 | |
|             return 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     # update the zone table
 | |
|     $rc = updatezonetable($request, $callback, $options, $keydir);
 | |
|     if ($rc == 0) {    # zone table setup is ok
 | |
|                        # update the nodelist table
 | |
|         if (defined($$options{'addnoderange'})) {
 | |
|             $rc = addnodestozone($request, $callback, $options, $keydir);
 | |
|         } else {       # note -a and -r are not allowed on one chzone
 | |
|             if (defined($$options{'rmnoderange'})) {
 | |
|                 $rc = rmnodesfromzone($request, $callback, $options, $keydir);
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return $rc;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
| 
 | |
|    Parses and runs rmzone
 | |
|    Input
 | |
|      request
 | |
|      callback
 | |
|      Input  arguments from the GetOpts
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub rmzone
 | |
| {
 | |
|     my ($request, $callback, $options) = @_;
 | |
| 
 | |
|     # already checked but lets do it again,  need a zonename, it is the only required parm
 | |
|     if (!($request->{zonename})) {
 | |
| 
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           "zonename not specified The zonename is required.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # see if they input invalid flags
 | |
|     if (($$options{'sshkeypath'}) || ($$options{'gensshkeys'}) ||
 | |
|         ($$options{'addnoderange'}) || ($$options{'rmnoderange'}) ||
 | |
|         ($$options{'defaultzone'}) ||
 | |
|         ($$options{'sshbetweennodes'})) {
 | |
| 
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
| "The following flags are not valid input for the rmzone command: -k,-K,-a,-r,-f,-s  ";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # check to see if the input zone already exists
 | |
|     # cannot remove it if it is not defined
 | |
|     my $zonename = $request->{zonename};
 | |
|     if (!(xCAT::Zone->iszonedefined($zonename))) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " zonename: $zonename is not defined. You cannot remove it.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # is this zone is the default zone you must force the delete
 | |
|     my $defaultzone = xCAT::Zone->getdefaultzone($callback);
 | |
|     if (($defaultzone eq $zonename) && (!($$options{'force'}))) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
| " You are removing the default zone: $zonename.  You must define another default zone before deleting or use the -f flag to force the removal.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # get the zone ssh key directory
 | |
|     my $sshrootkeydir = xCAT::Zone->getzonekeydir($zonename);
 | |
|     if ($sshrootkeydir == 1) {    # error return
 | |
|         my $rsp = {};
 | |
|         $rsp->{info}->[0] =
 | |
|           " sshkeydir attribute not defined for $zonename. Cannot remove it.";
 | |
|         xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|     } else {                      # remove the keys  unless it is /root/.ssh
 | |
|         my $roothome = xCAT::Utils->getHomeDir("root");
 | |
|         $roothome .= "\/.ssh";
 | |
|         if ($sshrootkeydir eq $roothome) {    # will not delete /root/.ssh
 | |
|             my $rsp = {};
 | |
|             $rsp->{info}->[0] =
 | |
|               "  $zonename sshkeydir is $roothome. This will not be deleted.";
 | |
|             xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|         } else {                              # not roothome/.ssh
 | |
|                # check to see if id_rsa.pub is there. I don't want to remove the
 | |
|                # wrong directory
 | |
|                # if id_rsa.pub exists remove the files
 | |
|                # then remove the directory
 | |
|             if (-e "$sshrootkeydir/id_rsa.pub") {
 | |
|                 my $cmd = "rm -rf $sshrootkeydir";
 | |
|                 xCAT::Utils->runcmd($cmd, 0);
 | |
|                 if ($::RUNCMD_RC != 0)
 | |
|                 {
 | |
|                     my $rsp = {};
 | |
|                     $rsp->{error}->[0] = "Command: $cmd failed";
 | |
|                     xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|                 }
 | |
|                 my ($zonedir, $ssh) = split(/\.ssh/, $sshrootkeydir);
 | |
|                 $cmd = "rmdir $zonedir";
 | |
|                 xCAT::Utils->runcmd($cmd, 0);
 | |
|                 if ($::RUNCMD_RC != 0)
 | |
|                 {
 | |
|                     my $rsp = {};
 | |
|                     $rsp->{error}->[0] = "Command: $cmd failed";
 | |
|                     xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|                 }
 | |
|             } else {    #  no id_rsa.pub key will not remove the files
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{info}->[0] = "$sshrootkeydir did not contain an id_rsa.pub key, will not remove files";
 | |
|                 xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|     }
 | |
| 
 | |
|     # open zone table and remove this entry
 | |
|     my $tab = xCAT::Table->new("zone");
 | |
|     if (!defined($tab)) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " Failure opening the zone table.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     # remove the table entry
 | |
|     $tab->delEntries({ zonename => $zonename });
 | |
| 
 | |
|     # remove zonename and possibly group name (-g flag) from  any nodes defined in this zone
 | |
|     my $rc = rmnodesfromzone($request, $callback, $options, "ALL");
 | |
| 
 | |
|     return $rc;
 | |
| 
 | |
| 
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|       usage
 | |
| 
 | |
|         puts out zone command usage message
 | |
| 
 | |
|         Arguments:
 | |
|           None
 | |
| 
 | |
|         Returns:
 | |
| 
 | |
|         Globals:
 | |
| 
 | |
| 
 | |
|         Error:
 | |
|                 None
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------------------------------
 | |
| 
 | |
| sub usage
 | |
| {
 | |
|     my ($callback, $command) = @_;
 | |
|     my $usagemsg1 = "";
 | |
|     my $usagemsg2 = "";
 | |
|     if ($command eq "mkzone") {
 | |
|         $usagemsg1 = " mkzone -h \n mkzone -v \n";
 | |
|         $usagemsg2 = " mkzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key>] \n        [-a <noderange>] [-g] [-f] [-s <yes/no>]";
 | |
|     } else {
 | |
|         if ($command eq "chzone") {
 | |
|             $usagemsg1 = " chzone -h \n chzone -v \n";
 | |
|             $usagemsg2 = " chzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key>] \n      [-K] [-a <noderange>] [-r <noderange>] [-g] [-s <yes/no>]";
 | |
|         } else {
 | |
|             if ($command eq "rmzone") {
 | |
|                 $usagemsg1 = " rmzone -h \n rmzone -v \n";
 | |
|                 $usagemsg2 = " rmzone <zonename> [-g]";
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     my $usagemsg .= $usagemsg1 .= $usagemsg2;
 | |
|     if ($callback)
 | |
|     {
 | |
|         my $rsp = {};
 | |
|         $rsp->{data}->[0] = $usagemsg;
 | |
|         xCAT::MsgUtils->message("I", $rsp, $callback);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         xCAT::MsgUtils->message("I", $usagemsg);
 | |
|     }
 | |
|     return;
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
| 
 | |
|    generate the ssh keys and store them in /etc/xcat/sshkeys/<zonename>/.ssh
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub gensshkeys
 | |
| {
 | |
|     my ($request, $callback, $options, $keydir) = @_;
 | |
|     my $rc = 0;
 | |
| 
 | |
|     # generate root ssh keys
 | |
|     # Did they input a path to existing RSA keys
 | |
|     my $rsakey;
 | |
|     my $zonename = $request->{zonename};
 | |
|     if ($$options{'sshkeypath'}) {
 | |
| 
 | |
|         # check to see if RSA keys exists
 | |
|         $rsakey = $$options{'sshkeypath'} .= "/id_rsa";
 | |
|         if (!(-e $rsakey)) {    # if it does not exist error out
 | |
|             my $rsp = {};
 | |
|             $rsp->{error}->[0] =
 | |
| "Input $rsakey does not exist.  Cannot generate the ssh root keys for the zone.";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|             return 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     $rc = xCAT::Zone->genSSHRootKeys($callback, $keydir, $zonename, $rsakey);
 | |
|     if ($rc != 0) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " Failure generating the ssh root keys for the zone.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
|     return $rc;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|     addtozonetable
 | |
|     Add the new zone to the zone table, check if already there and
 | |
|     error - use either chzone or -f to override default
 | |
| 
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub addtozonetable
 | |
| {
 | |
|     my ($request, $callback, $options, $keydir) = @_;
 | |
|     my $rc = 0;
 | |
|     my $zoneentry;
 | |
|     my $tab = xCAT::Table->new("zone");
 | |
|     if ($tab)
 | |
|     {
 | |
|         # read a record from the zone table, if it is empty then add
 | |
|         #  the xcatdefault entry
 | |
|         my @zones = $tab->getAllAttribs('zonename');
 | |
|         if (!(@zones)) {    # table empty
 | |
|             my %xcatdefaultzone;
 | |
|             $xcatdefaultzone{defaultzone}     = "yes";
 | |
|             $xcatdefaultzone{sshbetweennodes} = "yes";
 | |
|             my $roothome = xCAT::Utils->getHomeDir("root");
 | |
|             $roothome .= "\/.ssh";
 | |
|             $xcatdefaultzone{sshkeydir} = $roothome;
 | |
|             $tab->setAttribs({ zonename => "xcatdefault" }, \%xcatdefaultzone);
 | |
|         }
 | |
| 
 | |
|         # now add the users zone
 | |
|         my %tb_cols;
 | |
|         $tb_cols{sshkeydir} = $keydir;    # key directory
 | |
|              # set sshbetweennodes attribute from -s flag or default to yes
 | |
|         if ($$options{'sshbetweennodes'}) {
 | |
|             $tb_cols{sshbetweennodes} = $$options{'sshbetweennodes'};
 | |
|         } else {
 | |
|             $tb_cols{sshbetweennodes} = "yes";
 | |
|         }
 | |
|         my $zonename = $request->{zonename};
 | |
|         if ($$options{'defaultzone'}) {    # set the default
 | |
|                 # check to see if a default already defined
 | |
|             my $curdefaultzone = xCAT::Zone->getdefaultzone($callback);
 | |
|             if (!(defined($curdefaultzone))) {    # no default defined
 | |
|                 $tb_cols{defaultzone} = "yes";
 | |
|                 $tab->setAttribs({ zonename => $zonename }, \%tb_cols);
 | |
|                 $tab->commit();
 | |
|                 $tab->close();
 | |
|             } else {                              # already a default
 | |
|                 if ($$options{'force'}) {         # force the default
 | |
|                     $tb_cols{defaultzone} = "yes";
 | |
|                     $tab->setAttribs({ zonename => $zonename }, \%tb_cols);
 | |
| 
 | |
|                     # now change the old default zone to not be the default
 | |
|                     my %tb1_cols;
 | |
|                     $tb1_cols{defaultzone} = "no";
 | |
|                     $tab->setAttribs({ zonename => $curdefaultzone }, \%tb1_cols);
 | |
|                     $tab->commit();
 | |
|                     $tab->close();
 | |
|                 } else {                          # no force this is an error
 | |
|                     my $rsp = {};
 | |
|                     $rsp->{error}->[0] =
 | |
| " Failure setting default zone. The defaultzone $curdefaultzone already exists. Use the -f flag if you want to override the current default zone.";
 | |
|                     xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|                     return 1;
 | |
|                 }
 | |
|             }
 | |
|         } else {    # not a default zone
 | |
|             $tb_cols{defaultzone} = "no";
 | |
|             $tab->setAttribs({ zonename => $zonename }, \%tb_cols);
 | |
|             $tab->commit();
 | |
|             $tab->close();
 | |
|         }
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " Failure opening the zone table.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return $rc;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|     updatezonetable
 | |
|     change either the sshbetweennodes or defaultzone  attribute
 | |
|     or generate new keys ( -k -K)
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub updatezonetable
 | |
| {
 | |
|     my ($request, $callback, $options, $keydir) = @_;
 | |
|     my $zoneentry;
 | |
|     my $zonename = $request->{zonename};
 | |
| 
 | |
|     # check for changes
 | |
|     if (($$options{'sshbetweennodes'}) || ($$options{'defaultzone'}) ||
 | |
|         ($$options{'sshkeypath'}) || ($$options{'gensshkeys'})) {
 | |
| 
 | |
|         my $tab = xCAT::Table->new("zone");
 | |
|         if ($tab) {
 | |
| 
 | |
|             # now add the users changes
 | |
|             my %tb_cols;
 | |
| 
 | |
|             # generated keys ( -k or -K)
 | |
|             if (($$options{'sshkeypath'}) || ($$options{'gensshkeys'})) {
 | |
|                 $tb_cols{sshkeydir} = $keydir;    # key directory
 | |
|             }
 | |
| 
 | |
|             # set sshbetweennodes attribute from -s flag
 | |
|             if ($$options{'sshbetweennodes'}) {
 | |
|                 $tb_cols{sshbetweennodes} = $$options{'sshbetweennodes'};
 | |
|             }
 | |
| 
 | |
|             # if --defaultzone
 | |
|             if ($$options{'defaultzone'}) {       # set the default
 | |
|                     # check to see if a default already defined
 | |
|                 my $curdefaultzone = xCAT::Zone->getdefaultzone($callback);
 | |
|                 if (!(defined($curdefaultzone))) {    # no default defined
 | |
|                     $tb_cols{defaultzone} = "yes";
 | |
|                     $tab->setAttribs({ zonename => $zonename }, \%tb_cols);
 | |
|                     $tab->commit();
 | |
|                     $tab->close();
 | |
|                 } else {                              # already a default
 | |
|                     if ($$options{'force'}) {         # force the default
 | |
|                         $tb_cols{defaultzone} = "yes";
 | |
|                         $tab->setAttribs({ zonename => $zonename }, \%tb_cols);
 | |
| 
 | |
|                         # now change the old default zone to not be the default
 | |
|                         my %tb1_cols;
 | |
|                         $tb1_cols{defaultzone} = "no";
 | |
|                         $tab->setAttribs({ zonename => $curdefaultzone }, \%tb1_cols);
 | |
|                         $tab->commit();
 | |
|                         $tab->close();
 | |
|                     } else {    # no force this is an error
 | |
|                         my $rsp = {};
 | |
|                         $rsp->{error}->[0] =
 | |
| " Failure setting default zone. The defaultzone $curdefaultzone already exists. Use the -f flag if you want to override the current default zone.";
 | |
|                         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|                         return 1;
 | |
|                     }
 | |
|                 }
 | |
|             } else {  # not a default zone change, just commit the other changes
 | |
|                 $tab->setAttribs({ zonename => $zonename }, \%tb_cols);
 | |
|                 $tab->commit();
 | |
|                 $tab->close();
 | |
|             }
 | |
|         } else {
 | |
|             my $rsp = {};
 | |
|             $rsp->{error}->[0] =
 | |
|               " Failure opening the zone table.";
 | |
|             xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|             return 1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
| 
 | |
|     return 0;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|     addnodestozone
 | |
|     Add the new zonename attribute to any nodes in the noderange ( if a noderange specified)
 | |
|     Add zonename group to nodes in the noderange if -g flag.
 | |
| 
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub addnodestozone
 | |
| {
 | |
|     my ($request, $callback, $options, $keydir) = @_;
 | |
|     my $rc       = 0;
 | |
|     my $zonename = $request->{zonename};
 | |
| 
 | |
|     # if -g add zonename group also
 | |
|     my @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]);
 | |
| 
 | |
|     # check to see if noderange expanded
 | |
|     if (!(scalar @nodes)) {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
| " The noderange $request->{noderange}->[0] is not valid. The nodes are not defined.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
|     my $tab = xCAT::Table->new("nodelist");
 | |
|     if ($tab)
 | |
|     {
 | |
|         # if -g then add the zonename to the group attribute on each node
 | |
|         if ($$options{'assigngroup'}) {
 | |
|             foreach my $node (@nodes) {
 | |
|                 xCAT::TableUtils->updatenodegroups($node, $tab, $zonename);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         # set the nodelist zonename attribute to the zonename for all nodes in the range
 | |
|         $tab->setNodesAttribs(\@nodes, { zonename => $zonename });
 | |
|         $tab->commit();
 | |
|         $tab->close();
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " Failure opening the nodelist table.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
|     return $rc;
 | |
| 
 | |
| }
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| 
 | |
| =head3
 | |
|     rmnodesfromzone
 | |
|     removes the zonename from all nodes with their zonename the input zone or
 | |
|     the noderange supplied on the -r flag
 | |
|     if -g, removes zonename group from all nodes defined with their zonename the input zone.
 | |
|     Note if $ALL is input it removes all nodes from the zone,
 | |
|      otherwise  $request->{noderange} points to the noderange
 | |
| 
 | |
| 
 | |
| =cut
 | |
| 
 | |
| #-------------------------------------------------------
 | |
| sub rmnodesfromzone
 | |
| {
 | |
|     my ($request, $callback, $options, $ALL) = @_;
 | |
|     my $zonename = $request->{zonename};
 | |
|     my $tab      = xCAT::Table->new("nodelist");
 | |
|     if ($tab)
 | |
|     {
 | |
|         # read all the nodes with zonename
 | |
|         my @nodes;
 | |
|         if ($ALL) {    # do all nodes
 | |
|             @nodes = xCAT::Zone->getnodesinzone($callback, $zonename);
 | |
|         } else {       # the nodes in the noderange ( -r )
 | |
|             @nodes = xCAT::NodeRange::noderange($request->{noderange}->[0]);
 | |
| 
 | |
|             # check to see if noderange expanded
 | |
|             if (!(scalar @nodes)) {
 | |
|                 my $rsp = {};
 | |
|                 $rsp->{error}->[0] =
 | |
| " The noderange $request->{noderange}->[0] is not valid. The nodes are not defined.";
 | |
|                 xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|                 return 1;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         # if -g then remove the zonename  group attribute on each node
 | |
|         if ($$options{'assigngroup'}) {
 | |
|             foreach my $node (@nodes) {
 | |
|                 xCAT::TableUtils->rmnodegroups($node, $tab, $zonename);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         # set the nodelist zonename to nothing
 | |
|         my $nozonename = "";
 | |
|         $tab->setNodesAttribs(\@nodes, { zonename => $nozonename });
 | |
|         $tab->commit();
 | |
|         $tab->close();
 | |
|     } else {
 | |
|         my $rsp = {};
 | |
|         $rsp->{error}->[0] =
 | |
|           " Failure opening the nodelist table.";
 | |
|         xCAT::MsgUtils->message("E", $rsp, $callback);
 | |
|         return 1;
 | |
|     }
 | |
|     return 0;
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| 1;
 |