2014-02-13 12:53:31 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
#-------------------------------------------------------
= head1
2014-03-07 14:57:52 +00:00
xCAT plugin package to handle mkzone , chzone , Input rmzone commands
2014-02-13 12:53:31 +00:00
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
2014-02-24 16:39:36 +00:00
my $ keydir = "/etc/xcat/sshkeys/" ;
2014-02-13 12:53:31 +00:00
# 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 ;
}
2014-02-18 13:52:24 +00:00
# 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 ;
}
2014-02-13 12:53:31 +00:00
# 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
2014-03-10 18:43:35 +00:00
# Get the zonename if it is in the input
my @ SaveARGV = @ ARGV ;
2014-03-12 15:33:27 +00:00
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 ;
}
2014-03-10 18:43:35 +00:00
}
Getopt::Long:: Configure ( "posix_default" ) ;
Getopt::Long:: Configure ( "no_gnu_compat" ) ;
2014-02-13 12:53:31 +00:00
Getopt::Long:: Configure ( "bundling" ) ;
2014-03-10 18:43:35 +00:00
my % options = ( ) ;
2014-02-13 12:53:31 +00:00
if (
! GetOptions (
2014-03-10 18:43:35 +00:00
'a|noderange=s' = > \ $ options { 'addnoderange' } ,
'r|noderange=s' = > \ $ options { 'rmnoderange' } ,
2014-02-13 12:53:31 +00:00
'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' } ,
2014-02-19 13:48:43 +00:00
's|sshbetweennodes=s' = > \ $ options { 'sshbetweennodes' } ,
2014-02-13 12:53:31 +00:00
'v|version' = > \ $ options { 'version' } ,
'V|Verbose' = > \ $ options { 'verbose' } ,
)
)
{
& usage ( $ callback , $ command ) ;
exit 1 ;
}
2014-04-09 13:40:45 +00:00
# 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 ;
}
2014-02-13 12:53:31 +00:00
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
2014-03-10 18:43:35 +00:00
if ( ! $ zonename ) {
2014-02-13 12:53:31 +00:00
my $ rsp = { } ;
$ rsp - > { error } - > [ 0 ] =
2014-03-10 18:43:35 +00:00
"zonename not specified, it is required for this command." ;
2014-02-13 12:53:31 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
exit 1 ;
} else {
2014-03-10 18:43:35 +00:00
$ request - > { zonename } = $ zonename ;
2014-02-13 12:53:31 +00:00
}
2014-02-20 16:33:54 +00:00
# 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 ;
}
}
}
2014-04-09 13:40:45 +00:00
# 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 ;
}
2014-02-20 16:33:54 +00:00
# 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 ) ;
2014-03-10 18:43:35 +00:00
}
# -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' } ) {
2014-02-18 13:52:24 +00:00
# check to see if Management Node is in the noderange, if so error
2014-03-10 18:43:35 +00:00
$ 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' } ;
2014-02-18 13:52:24 +00:00
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 ;
}
2014-02-13 12:53:31 +00:00
}
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" )
{
2014-03-07 14:57:52 +00:00
$ rc = rmzone ( $ request , $ callback , \ % options ) ;
2014-02-13 12:53:31 +00:00
}
my $ rsp = { } ;
if ( $ rc == 0 ) {
$ rsp - > { info } - > [ 0 ] = "The $command ran successfully." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
} else {
2014-03-07 14:57:52 +00:00
$ rsp - > { error } - > [ 0 ] = "The $command had errors." ;
2014-02-13 12:53:31 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
}
return $ rc ;
}
#-------------------------------------------------------
= head3
Parses and runs mkzone
2014-03-07 14:57:52 +00:00
Input
request
callback
Input arguments from the GetOpts
zone ssh key dir
2014-02-13 12:53:31 +00:00
= 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 ] =
2014-03-07 14:57:52 +00:00
"zonename not specified The zonename is required." ;
2014-02-13 12:53:31 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
# test for -g, if no noderange this is an error
2014-03-10 18:43:35 +00:00
if ( ( ! defined ( $$ options { 'addnoderange' } ) ) && ( $$ options { 'assigngroup' } ) ) {
2014-02-13 12:53:31 +00:00
my $ rsp = { } ;
$ rsp - > { error } - > [ 0 ] =
" The -g flag requires a noderange ( -a)." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
2014-03-10 18:43:35 +00:00
# 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 ;
}
2014-02-13 12:53:31 +00:00
# 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
2014-03-07 14:57:52 +00:00
# keydir comes in set to /etc/xcat/sshkeys
2014-02-13 12:53:31 +00:00
$ keydir . = $ request - > { zonename } ;
2014-02-24 16:39:36 +00:00
$ keydir . = "/.ssh" ;
2014-02-19 13:48:43 +00:00
2014-02-13 12:53:31 +00:00
2014-03-10 18:43:35 +00:00
# add new zones to the zone table
$ rc = addtozonetable ( $ request , $ callback , $ options , $ keydir ) ;
2014-02-13 12:53:31 +00:00
if ( $ rc == 0 ) { # zone table setup is ok
2014-03-10 18:43:35 +00:00
# test for a noderange, if(-a) not supplied nothing to do
if ( defined ( $$ options { 'addnoderange' } ) ) {
$ rc = addnodestozone ( $ request , $ callback , $ options , $ keydir ) ;
}
2014-02-13 12:53:31 +00:00
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
2014-03-10 18:43:35 +00:00
Input
request
callback
Input arguments from the GetOpts
2014-02-13 12:53:31 +00:00
= cut
#-------------------------------------------------------
sub chzone
{
my ( $ request , $ callback , $ options , $ keydir ) = @ _ ;
2014-03-10 18:43:35 +00:00
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 } ) ) {
2014-02-13 12:53:31 +00:00
2014-03-10 18:43:35 +00:00
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' } ) ) &&
2014-03-11 18:19:36 +00:00
( ! ( $$ options { 'defaultzone' } ) ) &&
2014-03-10 18:43:35 +00:00
( ! ( $$ options { 'assigngroup' } ) ) && ( ! ( $$ options { 'sshbetweennodes' } ) ) ) {
my $ rsp = { } ;
$ rsp - > { info } - > [ 0 ] =
"chzone was run but nothing to do." ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
return 0 ;
}
2014-03-13 14:37:35 +00:00
# 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 ;
}
}
}
2014-03-10 18:43:35 +00:00
# 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 ) ;
}
}
}
2014-02-13 12:53:31 +00:00
2014-03-10 18:43:35 +00:00
return $ rc ;
2014-02-13 12:53:31 +00:00
}
#-------------------------------------------------------
= head3
Parses and runs rmzone
2014-03-07 14:57:52 +00:00
Input
request
callback
Input arguments from the GetOpts
2014-02-13 12:53:31 +00:00
= cut
#-------------------------------------------------------
sub rmzone
{
2014-03-07 14:57:52 +00:00
my ( $ request , $ callback , $ options ) = @ _ ;
# already checked but lets do it again, need a zonename, it is the only required parm
if ( ! ( $ request - > { zonename } ) ) {
2014-02-13 12:53:31 +00:00
2014-03-07 14:57:52 +00:00
my $ rsp = { } ;
$ rsp - > { error } - > [ 0 ] =
"zonename not specified The zonename is required." ;
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
2014-04-09 13:40:45 +00:00
# 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 ;
}
2014-03-07 14:57:52 +00:00
# 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 ;
}
2014-02-13 12:53:31 +00:00
2014-03-07 14:57:52 +00:00
# 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 ) ;
}
}
}
2014-02-13 12:53:31 +00:00
2014-03-07 14:57:52 +00:00
# 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
2014-03-10 18:43:35 +00:00
my $ rc = rmnodesfromzone ( $ request , $ callback , $ options , "ALL" ) ;
2014-03-07 14:57:52 +00:00
return $ rc ;
2014-02-13 12:53:31 +00:00
}
#-------------------------------------------------------------------------------
= 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" ;
2014-04-03 11:08:40 +00:00
$ usagemsg2 = " mkzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key>] \n [-a <noderange>] [-g] [-f] [-s <yes/no>]" ;
2014-02-13 12:53:31 +00:00
} else {
if ( $ command eq "chzone" ) {
$ usagemsg1 = " chzone -h \n chzone -v \n" ;
2014-04-03 11:08:40 +00:00
$ usagemsg2 = " chzone <zonename> [-V] [--defaultzone] [-k <full path to the ssh RSA private key>] \n [-K] [-a <noderange>] [-r <noderange>] [-g] [-s <yes/no>]" ;
2014-02-13 12:53:31 +00:00
} else {
if ( $ command eq "rmzone" ) {
$ usagemsg1 = " rmzone -h \n rmzone -v \n" ;
$ usagemsg2 = " rmzone <zonename> [-g]" ;
}
}
}
2014-03-07 14:57:52 +00:00
my $ usagemsg . = $ usagemsg1 . = $ usagemsg2 ;
2014-02-13 12:53:31 +00:00
if ( $ callback )
{
my $ rsp = { } ;
$ rsp - > { data } - > [ 0 ] = $ usagemsg ;
xCAT::MsgUtils - > message ( "I" , $ rsp , $ callback ) ;
}
else
{
xCAT::MsgUtils - > message ( "I" , $ usagemsg ) ;
}
return ;
}
#-------------------------------------------------------
= head3
2014-02-24 16:39:36 +00:00
generate the ssh keys and store them in /etc/xc at /sshkeys/ <zonename> / . ssh
2014-02-13 12:53:31 +00:00
= 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
2014-03-10 18:43:35 +00:00
addtozonetable
2014-02-13 12:53:31 +00:00
Add the new zone to the zone table , check if already there and
error - use either chzone or - f to override default
= cut
#-------------------------------------------------------
2014-03-10 18:43:35 +00:00
sub addtozonetable
2014-02-13 12:53:31 +00:00
{
my ( $ request , $ callback , $ options , $ keydir ) = @ _ ;
my $ rc = 0 ;
my $ zoneentry ;
my $ tab = xCAT::Table - > new ( "zone" ) ;
if ( $ tab )
{
2014-02-19 13:48:43 +00:00
# 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" ;
2014-02-24 16:39:36 +00:00
my $ roothome = xCAT::Utils - > getHomeDir ( "root" ) ;
$ roothome . = "\/.ssh" ;
$ xcatdefaultzone { sshkeydir } = $ roothome ;
2014-02-19 13:48:43 +00:00
$ tab - > setAttribs ( { zonename = > "xcatdefault" } , \ % xcatdefaultzone ) ;
}
# now add the users zone
2014-02-13 12:53:31 +00:00
my % tb_cols ;
2014-02-20 16:33:54 +00:00
$ 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" ;
}
2014-02-13 12:53:31 +00:00
my $ zonename = $ request - > { zonename } ;
if ( $$ options { 'defaultzone' } ) { # set the default
# check to see if a default already defined
2014-02-18 13:52:24 +00:00
my $ curdefaultzone = xCAT::Zone - > getdefaultzone ( $ callback ) ;
2014-02-13 12:53:31 +00:00
if ( ! ( defined ( $ curdefaultzone ) ) ) { # no default defined
$ tb_cols { defaultzone } = "yes" ;
2014-04-09 15:14:43 +00:00
$ tab - > setAttribs ( { zonename = > $ zonename } , \ % tb_cols ) ;
$ tab - > commit ( ) ;
$ tab - > close ( ) ;
2014-02-13 12:53:31 +00:00
} 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 ;
}
#-------------------------------------------------------
2014-03-10 18:43:35 +00:00
= head3
updatezonetable
2014-03-11 18:19:36 +00:00
change either the sshbetweennodes or defaultzone attribute
or generate new keys ( - k - K )
2014-03-10 18:43:35 +00:00
= cut
#-------------------------------------------------------
sub updatezonetable
{
my ( $ request , $ callback , $ options , $ keydir ) = @ _ ;
2014-03-11 18:19:36 +00:00
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 ) {
2014-03-10 18:43:35 +00:00
# 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" ;
2014-04-09 15:14:43 +00:00
$ tab - > setAttribs ( { zonename = > $ zonename } , \ % tb_cols ) ;
$ tab - > commit ( ) ;
$ tab - > close ( ) ;
2014-03-10 18:43:35 +00:00
} 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 ;
}
}
2014-03-11 18:19:36 +00:00
} 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 ] =
2014-03-10 18:43:35 +00:00
" Failure opening the zone table." ;
2014-03-11 18:19:36 +00:00
xCAT::MsgUtils - > message ( "E" , $ rsp , $ callback ) ;
return 1 ;
}
}
2014-03-10 18:43:35 +00:00
2014-03-11 18:19:36 +00:00
return 0 ;
2014-03-10 18:43:35 +00:00
}
#-------------------------------------------------------
2014-02-13 12:53:31 +00:00
= head3
2014-03-07 14:57:52 +00:00
addnodestozone
2014-02-13 12:53:31 +00:00
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
#-------------------------------------------------------
2014-03-07 14:57:52 +00:00
sub addnodestozone
2014-02-13 12:53:31 +00:00
{
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 ] ) ;
2014-03-10 18:43:35 +00:00
# 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 ;
}
2014-02-13 12:53:31 +00:00
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 ;
}
2014-03-07 14:57:52 +00:00
#-------------------------------------------------------
= head3
rmnodesfromzone
2014-03-10 18:43:35 +00:00
removes the zonename from all nodes with their zonename the input zone or
the noderange supplied on the - r flag
2014-03-07 14:57:52 +00:00
if - g , removes zonename group from all nodes defined with their zonename the input zone .
2014-03-10 18:43:35 +00:00
Note if $ ALL is input it removes all nodes from the zone ,
otherwise $ request - > { noderange } points to the noderange
2014-03-07 14:57:52 +00:00
= cut
#-------------------------------------------------------
sub rmnodesfromzone
{
2014-03-10 18:43:35 +00:00
my ( $ request , $ callback , $ options , $ ALL ) = @ _ ;
2014-03-07 14:57:52 +00:00
my $ zonename = $ request - > { zonename } ;
my $ tab = xCAT::Table - > new ( "nodelist" ) ;
if ( $ tab )
{
# read all the nodes with zonename
2014-03-10 18:43:35 +00:00
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 ;
}
}
2014-03-07 14:57:52 +00:00
# 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 ;
}
2014-02-13 12:53:31 +00:00
1 ;