# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html package xCAT::PPCdb; use strict; use xCAT::Table; use xCAT::GlobalDef; use xCAT::Utils; use xCAT::TableUtils; use xCAT::NetworkUtils; require xCAT::data::ibmhwtypes; ########################################### # Factory defaults ########################################### my %logon = ( hmc => [ "hscroot", "abc123" ], ivm => [ "padmin", "padmin" ], fsp => [ "admin", "admin" ], bpa => [ "admin", "admin" ], frame => [ "admin", "admin" ], cec => [ "admin", "admin" ], ); ########################################### # Tables based on HW Type ########################################### my %hcptab = ( hmc => "ppchcp", ivm => "ppchcp", fsp => "ppcdirect", bpa => "ppcdirect", frame => "ppcdirect", cec => "ppcdirect", blade => "mpa", ); ########################################### # The default groups of hcp ########################################### my %defaultgrp = ( hmc => "hmc", ivm => "ivm", fsp => "fsp", bpa => "bpa", frame => "frame", cec => "cec", blade => "blade", ); my %globlehwtype = ( fsp => $::NODETYPE_FSP, bpa => $::NODETYPE_BPA, lpar => $::NODETYPE_LPAR, hmc => $::NODETYPE_HMC, ivm => $::NODETYPE_IVM, frame => $::NODETYPE_FRAME, cec => $::NODETYPE_CEC, ); my %globalnodetype = ( fsp => $::NODETYPE_PPC, bpa => $::NODETYPE_PPC, cec => $::NODETYPE_PPC, frame => $::NODETYPE_PPC, hmc => $::NODETYPE_PPC, ivm => $::NODETYPE_PPC, lpar => "$::NODETYPE_PPC,$::NODETYPE_OSI" ); ########################################################################## # Adds a node to the xCAT databases ########################################################################## sub add_ppc { my $hwtype = shift; my $values = shift; my $not_overwrite = shift; my $otherinterfaces = shift; my $callfile = shift; my @tabs = qw(ppc vpd nodehm nodelist nodetype hosts mac); my %db = (); ################################### # Open database needed ################################### foreach (@tabs) { $db{$_} = xCAT::Table->new($_, -create => 1, -autocommit => 0); if (!$db{$_}) { return ("Error opening '$_'"); } } ################################### # Update tables ################################### foreach (@$values) { my ($type, $name, $id, $model, $serial, $side, $server, $pprofile, $parent, $ips, $mac) = split /,/; ############################### # Update nodetype table ############################### if ($type =~ /^(fsp|bpa|hmc|ivm|frame|cec)$/) { $db{nodetype}->setNodeAttribs($name, { nodetype => 'ppc' }); $db{nodetype}{commit} = 1; } elsif ($type =~ /^lpar$/) { $db{nodetype}->setNodeAttribs($name, { nodetype => 'ppc,osi' }); $db{nodetype}{commit} = 1; } ############################### # If cannot be overwroten, get # old data firstly ############################### my $mgt = $hwtype; # Specify CEC and Frame's mgt as fsp and bpa if ($type =~ /^cec$/) { if ($callfile eq "PPC") { $mgt = "hmc"; } if ($callfile eq "FSP") { $mgt = "fsp"; } } if ($type =~ /^frame$/) { $mgt = "bpa"; } my $cons = $hwtype; if ($not_overwrite) { my $enthash = $db{ppc}->getNodeAttribs($name, [qw(hcp id pprofile parent)]); if ($enthash) { $server = $enthash->{hcp} if ($enthash->{hcp}); $id = $enthash->{id} if ($enthash->{id}); $pprofile = $enthash->{pprofile} if ($enthash->{pprofile}); $parent = $enthash->{parent} if ($enthash->{parent}); } $enthash = $db{nodehm}->getNodeAttribs($name, [qw(mgt)]); if ($enthash) { $mgt = $enthash->{mgt} if ($enthash->{mgt}); $cons = $enthash->{cons} if ($enthash->{cons}); } $enthash = $db{vpd}->getNodeAttribs($name, [qw(mtm serial)]); if ($enthash) { $model = $enthash->{mtm} if ($enthash->{mtm}); $serial = $enthash->{serial} if ($enthash->{serial}); } } ############################### # Update ppc table ############################### if ($type =~ /^(fsp|bpa|lpar|frame|cec|hmc)$/) { $db{ppc}->setNodeAttribs($name, { hcp => $server, id => $id, pprofile => $pprofile, parent => $parent, nodetype => $globlehwtype{$type}, }); $db{ppc}{commit} = 1; ########################### # Update nodelist table ########################### updategroups($name, $db{nodelist}, $type); my $tmp_group = xCAT::data::ibmhwtypes::parse_group($model); if (defined($tmp_group)) { updategroups($name, $db{nodelist}, $tmp_group); } if ($type =~ /^(fsp|bpa)$/) { $db{nodelist}->setNodeAttribs($name, { hidden => '1' }); } else { $db{nodelist}->setNodeAttribs($name, { hidden => '0' }); } $db{nodelist}{commit} = 1; ########################### # Update nodehm table ########################### if ($type =~ /^lpar$/) { $db{nodehm}->setNodeAttribs($name, { mgt => $mgt, cons => $cons }); } else { $db{nodehm}->setNodeAttribs($name, { mgt => $mgt }); } $db{nodehm}{commit} = 1; } ############################### # Update vpd table ############################### if ($type =~ /^(fsp|bpa)$/) { $db{vpd}->setNodeAttribs($name, { mtm => $model, serial => $serial, side => $side }); } if ($type =~ /^(frame|cec)$/) { $db{vpd}->setNodeAttribs($name, { mtm => $model, serial => $serial, }); } $db{vpd}{commit} = 1; ############################### # Update hosts table ############################### if ($otherinterfaces) { $db{hosts}->setNodeAttribs($name, { otherinterfaces => $ips }); } else { $db{hosts}->setNodeAttribs($name, { ip => $ips }); } $db{hosts}{commit} = 1; ############################### # Update mac table ############################### if ($mac) { $db{mac}->setNodeAttribs($name, { mac => $mac }); } $db{mac}{commit} = 1; } ################################### # Commit changes ################################### foreach (@tabs) { if (exists($db{$_}{commit})) { $db{$_}->commit; } } return undef; } ########################################################################## # Update lpar information in the xCAT databases ########################################################################## sub update_lpar { my $hwtype = shift; my $values = shift; my $write = shift; my @tabs = qw(ppc vpd nodehm nodelist nodetype ppcdirect hosts mac); my %db = (); my @update_list = (); my @write_list = (); ################################### # Open database needed ################################### foreach (@tabs) { $db{$_} = xCAT::Table->new($_, -create => 1, -autocommit => 0); if (!$db{$_}) { return ("Error opening '$_'"); } } my @vpdlist = $db{vpd}->getAllNodeAttribs([ 'node', 'serial', 'mtm', 'side' ]); my @ppclist = $db{ppc}->getAllNodeAttribs([ 'node', 'hcp', 'id', 'pprofile', 'parent', 'nodetype', 'comments', 'disable' ]); # 'cec,cec1,,8246-L1D,100A9DA,,cec1,,cec1', # 'lpar,10-0A9DA,1,8246-L1D,100A9DA,,cec1,,cec1' my %ppchash = (); my %vpdhash = (); foreach my $ppcent (@ppclist) { if ($ppcent->{id} and $ppcent->{nodetype} and $ppcent->{nodetype} eq "lpar") { my $key = $ppcent->{node}; $ppchash{$key}{id} = $ppcent->{id}; $ppchash{$key}{parent} = $ppcent->{parent}; } } foreach my $vpdent (@vpdlist) { my $key = $vpdent->{node}; $vpdhash{$key}{mtm} = $vpdent->{mtm}; $vpdhash{$key}{serial} = $vpdent->{serial}; } my @ppc_lpars = keys %ppchash; foreach my $value (@$values) { my ($ttype, $tname, $tid, $tmtm, $tsn, $tside, $server, $pprofile, $parent) = split /,/, $value; if ($ttype ne "lpar") { push @update_list, $value; next; } my $find_node = undef; foreach my $tmp_node (@ppc_lpars) { if ($ppchash{$tmp_node}{id} eq $tid) { if (exists($ppchash{$tmp_node}{parent}) and $ppchash{$tmp_node}{parent} eq $parent) { $find_node = $tmp_node; last; } elsif ($vpdhash{$tmp_node}{mtm} eq $tmtm and $vpdhash{$tmp_node}{serial} eq $tsn) { $find_node = $tmp_node; last; } } } if (defined($find_node)) { if (update_node_attribs($hwtype, $ttype, $find_node, $tid, $tmtm, $tsn, $tside, $server, $pprofile, $parent, "", \%db, $tname, \@ppclist)) { $value =~ s/^$ttype,$tname,/$ttype,$find_node,/; push @update_list, $value; } } elsif (defined($write)) { push @write_list, $value; } } if (defined($write)) { &add_ppc($hwtype, \@write_list, '', '', "FSP"); return ([ @update_list, @write_list ]); } else { foreach (@tabs) { if (exists($db{$_}{commit})) { $db{$_}->commit; } } return \@update_list; } } ########################################################################## # Update nodes in the xCAT databases ########################################################################## sub update_ppc { my $hwtype = shift; my $values = shift; my $not_overwrite = shift; my @tabs = qw(ppc vpd nodehm nodelist nodetype ppcdirect hosts mac); my %db = (); my @update_list = (); ################################### # Open database needed ################################### foreach (@tabs) { $db{$_} = xCAT::Table->new($_, -create => 1, -autocommit => 0); if (!$db{$_}) { return ("Error opening '$_'"); } } my @vpdlist = $db{vpd}->getAllNodeAttribs([ 'node', 'serial', 'mtm', 'side' ]); my @hostslist = $db{hosts}->getAllNodeAttribs([ 'node', 'ip' ]); my @ppclist = $db{ppc}->getAllNodeAttribs([ 'node', 'hcp', 'id', 'pprofile', 'parent', 'supernode', 'comments', 'disable' ]); my @maclist = $db{mac}->getAllNodeAttribs([ 'node', 'mac' ]); ################################### # Need to do database migration first ################################### foreach my $value (@$values) { my ($ttype, $tname, $tid, $tmtm, $tsn, $tside, $server, $pprofile, $parent, $ips) = split /,/, $value; if ($ttype eq 'cec') { my $hostname = get_host($tname, "FSP", $tmtm, $tsn, "", "", $tid, "", ""); if ($hostname ne $tname) { $hostname =~ /\-(\w)$/; if ($1 =~ /^(A|B)$/) { $tside = $1; } if (update_node_attribs($hwtype, $ttype, $hostname, $tid, $tmtm, $tsn, $tside, $server, $pprofile, $parent, $ips, \%db, $tname, \@ppclist)) { push @update_list, $value; } } } elsif ($ttype eq 'frame') { my $hostname = get_host($tname, "BPA", $tmtm, $tsn, "", "", $tid, "", ""); if ($hostname ne $tname) { $hostname =~ /\-(\w)$/; if ($1 =~ /^(A|B)$/) { $tside = $1; } if (update_node_attribs($hwtype, $ttype, $hostname, $tid, $tmtm, $tsn, $tside, $server, $pprofile, $parent, $ips, \%db, $tname, \@ppclist)) { push @update_list, $value; } } } } ################################### # Update CEC in tables ################################### foreach my $value (@$values) { my ($type, $name, $id, $model, $serial, $side, $server, $pprofile, $parent, $ips) = split /,/, $value; next if ($type ne 'cec'); my $predefined_node = undef; foreach my $vpdent (@vpdlist) { if ($vpdent->{mtm} eq $model && $vpdent->{serial} eq $serial) { $predefined_node = $vpdent->{node}; if (update_node_attribs($hwtype, $type, $name, $id, $model, $serial, $side, $server, $pprofile, $parent, $ips, \%db, $predefined_node, \@ppclist)) { push @update_list, $value; } } } } my @newppclist = $db{ppc}->getAllNodeAttribs([ 'node', 'hcp', 'id', 'pprofile', 'parent', 'supernode', 'comments', 'disable' ]); ################################### # Update FRAME in tables ################################### foreach my $value (@$values) { my ($type, $name, $id, $model, $serial, $side, $server, $pprofile, $parent, $ips) = split /,/, $value; next if ($type ne 'frame'); my $predefined_node = undef; foreach my $vpdent (@vpdlist) { if ($vpdent->{mtm} eq $model && $vpdent->{serial} eq $serial && $vpdent->{side} eq $side) { $predefined_node = $vpdent->{node}; if (update_node_attribs($hwtype, $type, $name, $id, $model, $serial, $side, $server, $pprofile, $parent, $ips, \%db, $predefined_node, \@newppclist)) { push @update_list, $value; } } } } ################################### # Commit changes ################################### foreach (@tabs) { if (exists($db{$_}{commit})) { $db{$_}->commit; } } return \@update_list; } ########################################################################## # Update one node in the xCAT databases ########################################################################## sub update_node_attribs { my $mgt = shift; my $type = shift; my $name = shift; my $id = shift; my $model = shift; my $serial = shift; my $side = shift; my $server = shift; my $pprofile = shift; my $parent = shift; my $ips = shift; my $db = shift; my $predefined_node = shift; my $ppclist = shift; my $updated = undef; my $namediff = $name ne $predefined_node; my $key_col = { node => $predefined_node }; ############################# # update vpd table ############################# my $vpdhash = $db->{vpd}->getNodeAttribs($predefined_node, [qw(mtm serial)]); if ($model ne $vpdhash->{mtm} or $serial ne $vpdhash->{serial} or $namediff) { $db->{vpd}->delEntries($key_col) if ($namediff); $db->{vpd}->setNodeAttribs($name, { mtm => $model, serial => $serial, side => $side }); $db->{vpd}->{commit} = 1; $updated = 1; } ########################### # Update ppcdirect table ########################### my @users = qw(HMC admin general); foreach my $user (@users) { my $pwhash = $db->{ppcdirect}->getAttribs({ hcp => $predefined_node, username => $user }, qw(password comments disable)); # need regx if ($pwhash) { if ($namediff) { $db->{ppcdirect}->delEntries({ hcp => $predefined_node, username => $user }) if ($namediff); $db->{ppcdirect}->setAttribs({ hcp => $name, username => $user }, { password => $pwhash->{password}, comments => $pwhash->{comments}, disable => $pwhash->{disable} }); $db->{ppcdirect}->{commit} = 1; $updated = 1; } } } ############################# # update ppc table ############################# my $ppchash = $db->{ppc}->getNodeAttribs($predefined_node, [qw(hcp id pprofile parent)]); if ($ppchash->{parent} ne $predefined_node) { $parent = $ppchash->{parent}; } if ($server ne $ppchash->{hcp} or $id ne $ppchash->{id} or $pprofile ne $ppchash->{pprofile} or $parent ne $ppchash->{parent} or $type ne $ppchash->{nodetype} or $namediff) { $db->{ppc}->delEntries($key_col) if ($namediff); $db->{ppc}->setNodeAttribs($name, { hcp => $server, id => $id, pprofile => $pprofile, parent => $parent, nodetype => $globlehwtype{$type}, }); if ($namediff) { for my $ppcent (@$ppclist) { next if ($ppcent->{node} eq $predefined_node); if ($ppcent->{parent} eq $predefined_node) { $db->{ppc}->setNodeAttribs($ppcent->{node}, { parent => $name }); } } } $db->{ppc}->{commit} = 1; $updated = 1; } ########################### # Update nodehm table ########################### my $nodehmhash = $db->{nodehm}->getNodeAttribs($predefined_node, [qw(mgt)]); if ($mgt ne $nodehmhash->{mgt} or $namediff) { $db->{nodehm}->delEntries($key_col) if ($namediff); $db->{nodehm}->setNodeAttribs($name, { mgt => $mgt }); $db->{nodehm}->{commit} = 1; $updated = 1; } ########################### # Update nodetype table ########################### my $nodetypehash = $db->{nodetype}->getNodeAttribs($predefined_node, [qw(nodetype)]); if ($type ne $nodetypehash->{nodetype} or $namediff) { $db->{nodetype}->delEntries($key_col) if ($namediff); $db->{nodetype}->setNodeAttribs($name, { nodetype => $globalnodetype{$type} }); $db->{nodetype}->{commit} = 1; $updated = 1; } ########################### # Update nodelist table ########################### my $nodelisthash = $db->{nodelist}->getNodeAttribs($predefined_node, [qw(groups status appstatus primarysn comments disable)]); if ($namediff) { updategroups($name, $db->{nodelist}, $type); my $tmp_group = xCAT::data::ibmhwtypes::parse_group($model); if (defined($tmp_group)) { updategroups($name, $db->{nodelist}, $tmp_group); } $db->{nodelist}->setNodeAttribs($name, { status => $nodelisthash->{status}, appstatus => $nodelisthash->{appstatus}, primarysn => $nodelisthash->{primarysn}, comments => $nodelisthash->{comments}, disable => $nodelisthash->{disable} }); $db->{nodelist}->delEntries($key_col); $db->{nodelist}->{commit} = 1; $updated = 1; } ########################### # Update hosts table ########################### my $hostslisthash = $db->{hosts}->getNodeAttribs($predefined_node, [qw(ip otherinterfaces)]); if ($namediff) { $db->{hosts}->delEntries($key_col); $db->{hosts}->setNodeAttribs($name, { ip => $ips, otherinterfaces => $hostslisthash->{otherinterfaces} }); $db->{hosts}->{commit} = 1; $updated = 1; } ########################### # Update mac table ########################### my $maclisthash = $db->{mac}->getNodeAttribs($predefined_node, [qw(mac)]); if ($namediff) { $db->{mac}->delEntries($key_col); $db->{mac}->setNodeAttribs($name, { mac => $maclisthash->{mac} }); $db->{mac}->{commit} = 1; $updated = 1; } return $updated; } ########################################################################## # Updates the nodelist.groups attribute ########################################################################## sub updategroups { my $name = shift; my $tab = shift; my $hwtype = shift; ############################### # Get current value ############################### my ($ent) = $tab->getNodeAttribs($name, ['groups']); my @list = (lc($hwtype), "all"); ############################### # Keep any existing groups ############################### if (defined($ent) and $ent->{groups}) { push @list, split(/,/, $ent->{groups}); } ############################### # Remove duplicates ############################### my %saw; @saw{@list} = (); @list = keys %saw; $tab->setNodeAttribs($name, { groups => join(",", @list) }); } ########################################################################## # Adds an HMC/IVM to the xCAT database ########################################################################## sub add_ppchcp { my $hwtype = shift; my $values = shift; my @tabs = qw(ppchcp nodehm nodelist nodetype mac ppc vpd); my %db = (); my ($name, $mac, $mtm, $sn, $ip) = split ',', $values; ################################### # Open database needed ################################### foreach (@tabs) { $db{$_} = xCAT::Table->new($_, -create => 1, -autocommit => 1); if (!$db{$_}) { return ("Error opening '$_'"); } } ################################### # Update ppchcp table ################################### my ($ent) = $db{ppchcp}->getNodeAttribs($name, 'hcp'); if (!defined($ent)) { $db{ppchcp}->setAttribs({ hcp => $name }, { username => "", password => "" }); } ################################### # Update nodehm table ################################### $db{nodehm}->setNodeAttribs($name, { mgt => lc($hwtype) }); ################################### # Update nodetype table ################################### $db{nodetype}->setNodeAttribs($name, { nodetype => $globalnodetype{$hwtype} }); $db{ppc}->setNodeAttribs($name, { nodetype => $globlehwtype{$hwtype} }); ################################### # Update mac table ################################### $db{mac}->setNodeAttribs($name, { mac => $mac }); ################################### # Update vpd table ################################### $db{vpd}->setNodeAttribs($name, { mtm => $mtm }); $db{vpd}->setNodeAttribs($name, { serial => $sn }); ################################### # Update nodelist table ################################### updategroups($name, $db{nodelist}, $hwtype); return undef; } ########################################################################## # Removes a node from the xCAT databases ########################################################################## sub rm_ppc { my $node = shift; my @tabs = qw(ppc nodehm nodelist); foreach (@tabs) { ################################### # Open table ################################### my $tab = xCAT::Table->new($_); if (!$tab) { return ("Error opening '$_'"); } ############################### # Remove entry ############################### $tab->delEntries({ 'node' => $node }); } return undef; } ########################################################################## # Adds a Management-Module or RSA to the appropriate tables ########################################################################## sub add_systemX { my $hwtype = shift; my $name = shift; my $data = shift; my @tabs = qw(mpa mp nodehm nodelist); my %db = (); ################################### # Open database needed ################################### foreach (@tabs) { $db{$_} = xCAT::Table->new($_, -create => 1, -autocommit => 1); if (!$db{$_}) { return ("Error opening '$_'"); } } ################################### # Update mpa table ################################### my ($ent) = $db{mpa}->getNodeAttribs($name, 'mpa'); if (!defined($ent)) { $db{mpa}->setAttribs({ mpa => $name }, { username => "", password => "" }); } ################################### # Update mp table ################################### $db{mp}->setNodeAttribs($name, { mpa => $name, id => "0" }); ################################### # Update nodehm table ################################### $db{nodehm}->setNodeAttribs($name, { mgt => "blade" }); ################################### # Update nodelist table ################################### updategroups($name, $db{nodelist}, $hwtype); return undef; } ########################################################################## # Get userids and passwords from tables ########################################################################## sub credentials { my $server = shift; my $hwtype = shift; my $user = shift; my $pass = undef; my $user_specified = $user; if (!$user_specified or $user eq @{ $logon{$hwtype} }[0]) { $user = @{ $logon{$hwtype} }[0]; $pass = @{ $logon{$hwtype} }[1]; } ########################################### # find parent for fsp/bpa, use parent's attributes first ########################################### my $ntype = xCAT::DBobjUtils->getnodetype($server, "ppc"); if ($ntype =~ /^(fsp|bpa)$/) { my $ptab = xCAT::Table->new('ppc'); if ($ptab) { my $parent = $ptab->getNodeAttribs($server, ["parent"]); if ($parent and $parent->{parent}) { my $ptype = xCAT::DBobjUtils->getnodetype($parent->{parent}, "ppc"); if (($ptype =~ /^cec$/ and $ntype =~ /^fsp$/) or ($ptype =~ /^frame$/ and $ntype =~ /^bpa$/)) { $server = $parent->{parent}; } } } } ########################################### # Check passwd tab ########################################### #my $tab = xCAT::Table->new( 'passwd' ); #if ( $tab ) { #my $ent; # if ( $user_specified) # { # ($ent) = $tab->getAttribs( {key=>$hwtype,username=>$user},qw(password)); # } # else # { # ($ent) = $tab->getAttribs( {key=>$hwtype}, qw(username password)); # } # if ( $ent ) { # if (defined($ent->{password})) { $pass = $ent->{password}; } # if (defined($ent->{username})) { $user = $ent->{username}; } # } #} my ($ent) = get_usr_passwd($hwtype, $user); if ($ent) { if (defined($ent->{password})) { $pass = $ent->{password}; } if (defined($ent->{username})) { $user = $ent->{username}; } } ########################################## # Check table based on specific node ########################################## my $tab = xCAT::Table->new($hcptab{$hwtype}); if ($tab) { my $ent; if ($user_specified) { # need regx #($ent) = $tab->getAttribs( {hcp=>$server,username=>$user},qw(password)); #($ent) = $tab->getNodeSpecAttribs( $server, {username=>$user},qw(password)); my @output = $tab->getNodeAttribs($server, qw(username password)); foreach my $tmp_entry (@output) { if ($tmp_entry->{username} =~ /^$user$/) { $ent = $tmp_entry; last; } } } else { ($ent) = $tab->getNodeAttribs($server, qw(username password)); } if ($ent) { if (defined($ent->{password})) { $pass = $ent->{password}; } if (defined($ent->{username})) { $user = $ent->{username}; } } ############################################################## # If no user/passwd found, check if there is a default group ############################################################## else { if ($user_specified) { # need regx #($ent) = $tab->getAllAttribs( {hcp=>$defaultgrp{$hwtype},username=>$user},qw(password)); #($ent) = $tab->getNodeSpecAttribs( $defaultgrp{$hwtype}, {username=>$user},qw(password)); my @output = $tab->getNodeAttribs($defaultgrp{$hwtype}, qw(username password)); foreach my $tmp_entry (@output) { if ($tmp_entry->{username} =~ /^$user$/) { $ent = $tmp_entry; last; } } } else { ($ent) = $tab->getNodeAttribs($defaultgrp{$hwtype}, qw(username password)); } if ($ent) { if (defined($ent->{password})) { $pass = $ent->{password}; } if (defined($ent->{username})) { $user = $ent->{username}; } } } } return ($user, $pass); } ########################################################################## # Get password for user in 'passwd' table, if doesn't exist, use default # password for this user. ########################################################################## my %power_accounts = ( HMC => 'abc123', general => 'general', admin => 'admin', ); my %default_passwd_accounts = ( system => { root => 'cluster', }, hmc => { hscroot => 'abc123', }, fsp => \%power_accounts, bpa => \%power_accounts, frame => \%power_accounts, cec => \%power_accounts, blade => { USERID => 'PASSW0RD', HMC => 'PASSW0RD' }, ipmi => { USERID => 'PASSW0RD', }, ivm => { padmin => 'padmin', }, vmware => { root => '', }, vcenter => { Administrator => '' }, ); sub get_usr_passwd { my $key = shift; if ($key && ($key =~ /xCAT::/)) { $key = shift; } my $user = shift; my $ent; my $passwdtab = xCAT::Table->new('passwd'); if (!$passwdtab) { return undef; } if ($user) { ($ent) = $passwdtab->getAttribs({ key => $key, username => $user }, qw(password cryptmethod)); } else { ($ent) = $passwdtab->getNodeAttribs($key, qw(username password)); } if (!$ent) { if ($key eq "cec") { $key = "fsp"; } elsif ($key eq "frame") { $key = "bpa"; } if ($user) { ($ent) = $passwdtab->getAttribs({ key => $key, username => $user }, qw(password cryptmethod)); } else { ($ent) = $passwdtab->getNodeAttribs($key, qw(username password)); } } if (!$ent or !$ent->{password}) { my $hash = $default_passwd_accounts{$key}; if (!$hash or ($user and !defined($hash->{$user}))) { return undef; } if (!$user) { my @tmp_keys = keys(%$hash); $user = $tmp_keys[0]; } $ent->{username} = $user; $ent->{password} = $hash->{$user}; } return $ent; } ########################################################################## # Set userids and passwords to tables ########################################################################## sub update_credentials { my $server = shift; my $hwtype = shift; my $user = shift; my $pass = shift; ########################################## # Set password to specific table ########################################## my $tab = xCAT::Table->new($hcptab{$hwtype}); if ($tab) { my $ent; $tab->setAttribs({ hcp => $server, username => $user }, { password => $pass }); } return undef; } ############################################################################# # used for FSP/BPA redundancy database migration # if return something, it means it will use the old data name # or new data name # if return undef, it means the ip is not invalid and won't make any definition ############################################################################# sub get_host { my $nodename = shift; my $type = shift; my $mtm = shift; my $sn = shift; my $side = shift; my $ip = shift; my $cage_number = shift; my $parmtm = shift; my $parsn = shift; my $pname = shift; my $flagref = shift; ####################################### # Extract IP from URL ####################################### if ($ip) { my $nets = xCAT::NetworkUtils::my_nets(); my $avip = getip_from_iplist($ip, $nets); #if ( !defined( $ip )) { # return undef; #} } # get the information of existed nodes to do the migration read_from_table() unless (%::OLD_DATA_CACHE); foreach my $oldnode (keys %::OLD_DATA_CACHE) { my $tmpmtm = @{ $::OLD_DATA_CACHE{$oldnode} }[0]; my $tmpsn = @{ $::OLD_DATA_CACHE{$oldnode} }[1]; my $tmpside = @{ $::OLD_DATA_CACHE{$oldnode} }[2]; my $tmpip = @{ $::OLD_DATA_CACHE{$oldnode} }[3]; my $tmpid = @{ $::OLD_DATA_CACHE{$oldnode} }[4]; my $tmpparent = @{ $::OLD_DATA_CACHE{$oldnode} }[5]; my $tmptype = uc(@{ $::OLD_DATA_CACHE{$oldnode} }[6]); my $unmatched = @{ $::OLD_DATA_CACHE{$oldnode} }[7]; # used to match fsp defined by xcatsetup # should return fast to save time if (($type eq "BPA" or $type eq "FSP") and ($tmptype eq $type) and $pname and $side) { if ($pname eq $tmpparent and $side eq $tmpside) { $$flagref = 1; return $oldnode; } } # match the existed nodes including old data and user defined data if (($type eq "BPA" or $type eq "FSP") and ($tmptype eq $type)) { unless ($tmpmtm) { next; } if ($tmpmtm eq $mtm and $tmpsn eq $sn) { my $ifip = xCAT::NetworkUtils->isIpaddr($oldnode); if ($ifip) { # which means that the node is defined by the new lsslp if ($tmpside eq $side) { # match! which means that node is the same as the new one if ($ip eq $tmpip) { #which means that the ip is not changed # maybe we should check if the ip is invalid and send a warning $$flagref = 1; return $ip; } else { #which means that the ip is changed my $vip = check_ip($ip); if (!$vip) { #which means the ip is changed and valid # maybe we should check if the old ip is invalid and send a warning # even so we should keep the definition as before # because this case, we can't put check_ip in the end $$flagref = 1; return $oldnode; } else { return $ip; } } } } else { # name is not a ip $side =~ /(\w)\-(\w)/; my $slot = $1; if ($tmpside and $tmpside !~ /\-/) { # side is like A or B if ($slot eq $tmpside) { if ($oldnode =~ /^Server\-/) { #judge if need to change node's name if ($ip eq $tmpip) { if ($oldnode =~ /\-(A|B)$/) { @{ $::OLD_DATA_CACHE{$oldnode} }[7] = 0; $$flagref = 1; return $oldnode; } else { @{ $::OLD_DATA_CACHE{$oldnode} }[7] = 0; #change node name, need to record the node here $::UPDATE_CACHE{ $mtm . '-' . $sn } = $oldnode; $$flagref = 1; return $oldnode . '-' . $slot; } } else { # not find a matched definition, but need to use the old node name if ($unmatched) { $$flagref = 1; return $oldnode; } } } elsif ($tmpside =~ /\-/) { # end of if ( $oldnode =~ /^Server\-/) if ($ip eq $tmpip) { @{ $::OLD_DATA_CACHE{$oldnode} }[7] = 0; $$flagref = 1; return $oldnode; } else { if ($unmatched) { $$flagref = 1; return $oldnode; } } } } } elsif ($tmpside =~ /\-/) { if ($side eq $tmpside) { $$flagref = 1; return $oldnode; } } elsif (!$tmpside) { if ($oldnode =~ /^Server\-/) { #judge if need to change node's name if ($oldnode !~ /\-(A|B)$/) { delete $::OLD_DATA_CACHE{$oldnode}; $$flagref = 1; return $oldnode . "-" . $slot; } } # if mtms could match but side not defined, we will trate # it as the result by rscan. And alway use its name. delete $::OLD_DATA_CACHE{$oldnode}; $$flagref = 1; return $oldnode; } } } # end of if ($tmpmtm eq $mtm and $tmpsn eq $sn) } if (($type eq "FRAME" or $type eq "CEC") and ($type eq $tmptype)) { if (!$tmpmtm and !$tmpid) { next; } # user may define cec only with parent /id /type # we should match this situation if (($type eq "CEC") and $parmtm and $parsn and $cage_number) { my $tpparmtm = @{ $::OLD_DATA_CACHE{$tmpparent} }[0]; my $tpparsn = @{ $::OLD_DATA_CACHE{$tmpparent} }[1]; if (($tpparmtm eq $parmtm) and ($tpparsn eq $parsn) and ($cage_number eq $tmpid) and ($type eq $tmptype)) { $$flagref = 1; return $oldnode; } } # user may define cec/frame only with mtms # but what we consider here is just the data in xCAT 2.6 if ($tmpmtm eq $mtm and $tmpsn eq $sn and $tmptype eq $type) { if ($oldnode =~ /^Server\-/) { #judge if need to change node's name if ($oldnode =~ /(\-A)$/) { $nodename =~ s/(\-A)$//; # should send a warning here $$flagref = 1; return $nodename; } else { $$flagref = 1; return $oldnode; } } else { $$flagref = 1; return $oldnode; } } } # end of foreach my $oldnode ( keys %::OLD_DATA_CACHE ), not match } # not matched, use the new name my $ifip = xCAT::NetworkUtils->isIpaddr($nodename); unless ($ifip) { return $nodename; } else { my $vip = check_ip($nodename); if ($vip) { #which means the ip is a valid one return $nodename; } else { return undef; } } } ########################################################################## # Get correct IP from ip list in SLP Attr ########################################################################## sub getip_from_iplist { my $iplist = shift; my $nets = shift; my $inc = shift; my @ips = split /,/, $iplist; my @ips2 = split /,/, $inc; if ($inc) { for my $net (keys %$nets) { my $flag = 1; for my $einc (@ips2) { if ($nets->{$net} eq $einc) { $flag = 0; } } delete $nets->{$net} if ($flag); } } for my $ip (@ips) { next if ($ip =~ /:/); #skip IPV6 addresses for my $net (keys %$nets) { my ($n, $m) = split /\//, $net; if (xCAT::NetworkUtils::isInSameSubnet($n, $ip, $m, 1) and xCAT::NetworkUtils::isPingable($ip)) { return $ip; } } } return undef; } sub read_from_table { my %idhash; my %typehash; my %iphash; my %vpdhash; if (!(%::OLD_DATA_CACHE)) { # find out all the existed nodes' ipaddresses my $hoststab = xCAT::Table->new('hosts'); if ($hoststab) { my @ipentries = $hoststab->getAllNodeAttribs([ 'node', 'ip' ]); for my $ipentry (@ipentries) { $iphash{ $ipentry->{node} } = $ipentry->{ip}; } } else { return 1; } #find out all the existed nodes' type my $nodetypetab = xCAT::Table->new('nodetype'); if ($nodetypetab) { my @typeentries = $nodetypetab->getAllNodeAttribs([ 'node', 'nodetype' ]); for my $typeentry (@typeentries) { $typehash{ $typeentry->{node} } = $typeentry->{nodetype}; } } else { return 2; } # find out all the existed nodes' mtms and side my $vpdtab = xCAT::Table->new('vpd'); if ($vpdtab) { my @vpdentries = $vpdtab->getAllNodeAttribs([ 'node', 'mtm', 'serial', 'side' ]); for my $entry (@vpdentries) { @{ $vpdhash{ $entry->{node} } }[0] = $entry->{mtm}; @{ $vpdhash{ $entry->{node} } }[1] = $entry->{serial}; @{ $vpdhash{ $entry->{node} } }[2] = $entry->{side}; } } else { return 3; } # find out all the existed nodes' attributes my $ppctab = xCAT::Table->new('ppc'); if ($ppctab) { my @identries = $ppctab->getAllNodeAttribs([ 'node', 'id', 'parent', 'nodetype' ]); for my $entry (@identries) { next if ($entry->{nodetype} =~ /lpar/); @{ $::OLD_DATA_CACHE{ $entry->{node} } }[0] = @{ $vpdhash{ $entry->{node} } }[0]; #mtm @{ $::OLD_DATA_CACHE{ $entry->{node} } }[1] = @{ $vpdhash{ $entry->{node} } }[1]; #sn @{ $::OLD_DATA_CACHE{ $entry->{node} } }[2] = @{ $vpdhash{ $entry->{node} } }[2]; #side # find node ip address, check node name first, then check hosts table my $ifip = xCAT::NetworkUtils->isIpaddr($entry->{node}); if ($ifip) { @{ $::OLD_DATA_CACHE{ $entry->{node} } }[3] = $entry->{node}; #ip } else { if (exists($iphash{ $entry->{node} })) { @{ $::OLD_DATA_CACHE{ $entry->{node} } }[3] = $iphash{ $entry->{node} }; #ip } else { @{ $::OLD_DATA_CACHE{ $entry->{node} } }[3] = ""; #ip } } @{ $::OLD_DATA_CACHE{ $entry->{node} } }[4] = $entry->{id}; #id @{ $::OLD_DATA_CACHE{ $entry->{node} } }[5] = $entry->{parent}; #parent if (exists $entry->{nodetype}) { @{ $::OLD_DATA_CACHE{ $entry->{node} } }[6] = $entry->{nodetype}; #nodetype } else { if (exists($typehash{ $entry->{node} })) { @{ $::OLD_DATA_CACHE{ $entry->{node} } }[6] = $typehash{ $entry->{node} }; } else { @{ $::OLD_DATA_CACHE{ $entry->{node} } }[6] = ""; } } @{ $::OLD_DATA_CACHE{ $entry->{node} } }[7] = 1; } } else { return 4; } } return 0; } ########################################################################## # Makesure the ip in SLP URL is valid # return 1 if valid, 0 if invalid ########################################################################## sub check_ip { my $myip = shift; my $firstoctet = $myip; my @invalidiplist = ( "192.168.2.144", "192.168.2.145", "192.168.2.146", "192.168.2.147", "192.168.2.148", "192.168.2.149", "192.168.3.144", "192.168.3.145", "192.168.3.146", "192.168.3.147", "192.168.3.148", "192.168.3.149", "169.254.", "127.0.0.0", "127", 0, ); $firstoctet =~ s/^(\d+)\..*/$1/; if ($firstoctet >= 224 and $firstoctet <= 239) { return 0; } foreach (@invalidiplist) { if ($myip =~ /^($_)/) { return 0; } } return 1; } 1;