From 6db569b83c5d56eceff2470d7a6943b97b5f2de2 Mon Sep 17 00:00:00 2001 From: xuweibj Date: Tue, 5 Jun 2018 04:14:59 -0400 Subject: [PATCH] Add redfish support perl part --- .../admin-guides/references/man5/nodehm.5.rst | 2 +- .../admin-guides/references/man7/group.7.rst | 2 +- .../admin-guides/references/man7/node.7.rst | 2 +- perl-xCAT/xCAT/Schema.pm | 33 ++- xCAT-server/lib/xcat/plugins/redfish.pm | 233 ++++++++++++++++++ 5 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 xCAT-server/lib/xcat/plugins/redfish.pm diff --git a/docs/source/guides/admin-guides/references/man5/nodehm.5.rst b/docs/source/guides/admin-guides/references/man5/nodehm.5.rst index aa12ce4b2..6888ce67b 100644 --- a/docs/source/guides/admin-guides/references/man5/nodehm.5.rst +++ b/docs/source/guides/admin-guides/references/man5/nodehm.5.rst @@ -50,7 +50,7 @@ nodehm Attributes: \ **mgt**\ - The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details. + The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, redfish, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details. diff --git a/docs/source/guides/admin-guides/references/man7/group.7.rst b/docs/source/guides/admin-guides/references/man7/group.7.rst index f4507f8e8..c561b7dfa 100644 --- a/docs/source/guides/admin-guides/references/man7/group.7.rst +++ b/docs/source/guides/admin-guides/references/man7/group.7.rst @@ -501,7 +501,7 @@ group Attributes: \ **mgt**\ (nodehm.mgt) - The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details. + The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, redfish, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details. diff --git a/docs/source/guides/admin-guides/references/man7/node.7.rst b/docs/source/guides/admin-guides/references/man7/node.7.rst index 985dadec3..d08820260 100644 --- a/docs/source/guides/admin-guides/references/man7/node.7.rst +++ b/docs/source/guides/admin-guides/references/man7/node.7.rst @@ -501,7 +501,7 @@ node Attributes: \ **mgt**\ (nodehm.mgt) - The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details. + The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, redfish, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details. diff --git a/perl-xCAT/xCAT/Schema.pm b/perl-xCAT/xCAT/Schema.pm index 3c1fe110f..56308a95c 100755 --- a/perl-xCAT/xCAT/Schema.pm +++ b/perl-xCAT/xCAT/Schema.pm @@ -601,7 +601,7 @@ passed as argument rather than by table value', descriptions => { node => 'The node name or group name.', power => 'The method to use to control the power of the node. If not set, the mgt attribute will be used. Valid values: ipmi, blade, hmc, ivm, fsp, kvm, esx, rhevm. If "ipmi", xCAT will search for this node in the ipmi table for more info. If "blade", xCAT will search for this node in the mp table. If "hmc", "ivm", or "fsp", xCAT will search for this node in the ppc table.', - mgt => 'The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details.', + mgt => 'The method to use to do general hardware management of the node. This attribute is used as the default if power or getmac is not set. Valid values: openbmc, redfish, ipmi, blade, hmc, ivm, fsp, bpa, kvm, esx, rhevm. See the power attribute for more details.', cons => 'The console method. If nodehm.serialport is set, this will default to the nodehm.mgt setting, otherwise it defaults to unused. Valid values: cyclades, mrv, or the values valid for the mgt attribute.', termserver => 'The hostname of the terminal server.', termport => 'The port number on the terminal server that this node is connected to.', @@ -2367,6 +2367,11 @@ my @nodeattrs = ( tabentry => 'mp.nodetype', access_tabentry => 'mp.node=attr:node', }, + { attr_name => 'hwtype', + only_if => 'mgt=redfish', + tabentry => 'mp.nodetype', + access_tabentry => 'mp.node=attr:node', + }, { attr_name => 'supernode', tabentry => 'ppc.supernode', access_tabentry => 'ppc.node=attr:node', @@ -2556,6 +2561,32 @@ my @nodeattrs = ( access_tabentry => 'openbmc.node=attr:node', }, + { attr_name => 'bmc', + only_if => 'mgt=redfish', + tabentry => 'openbmc.bmc', + access_tabentry => 'openbmc.node=attr:node', + }, + { attr_name => 'bmcusername', + only_if => 'mgt=redfish', + tabentry => 'openbmc.username', + access_tabentry => 'openbmc.node=attr:node', + }, + { attr_name => 'bmcpassword', + only_if => 'mgt=redfish', + tabentry => 'openbmc.password', + access_tabentry => 'openbmc.node=attr:node', + }, + { attr_name => 'consport', + only_if => 'mgt=redfish', + tabentry => 'openbmc.consport', + access_tabentry => 'openbmc.node=attr:node', + }, + { attr_name => 'bmcvlantag', + only_if => 'mgt=redfish', + tabentry => 'openbmc.taggedvlan', + access_tabentry => 'openbmc.node=attr:node', + }, + ###################### # nodepos table # ###################### diff --git a/xCAT-server/lib/xcat/plugins/redfish.pm b/xCAT-server/lib/xcat/plugins/redfish.pm new file mode 100644 index 000000000..752a8a9b3 --- /dev/null +++ b/xCAT-server/lib/xcat/plugins/redfish.pm @@ -0,0 +1,233 @@ +#!/usr/bin/perl +### IBM(c) 2017 EPL license http://www.eclipse.org/legal/epl-v10.html + +package xCAT_plugin::redfish; + +BEGIN + { + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; + } +use lib "$::XCATROOT/lib/perl"; +use strict; +use warnings "all"; + +use Getopt::Long; +use xCAT::Usage; +use xCAT::SvrUtils; +use xCAT::AGENT; + +#------------------------------------------------------- + +=head3 handled_commands + + Return list of commands handled by this plugin + +=cut + +#------------------------------------------------------- + +sub handled_commands { + return { + rbeacon => 'nodehm:mgt', + reventlog => 'nodehm:mgt', + rinv => 'nodehm:mgt', + rpower => 'nodehm:mgt', + rsetboot => 'nodehm:mgt', + rspconfig => 'nodehm:mgt', + rvitals => 'nodehm:mgt', + }; +} + +my %node_info = (); +my $callback; +$::VERBOSE = 0; + +#------------------------------------------------------- + +=head3 preprocess_request + + preprocess the command + +=cut + +#------------------------------------------------------- + +sub preprocess_request { + my $request = shift; + $callback = shift; + my $command = $request->{command}->[0]; + my $noderange = $request->{node}; + my $extrargs = $request->{arg}; + my @exargs = ($request->{arg}); + my @requests; + + if (ref($extrargs)) { + @exargs = @$extrargs; + } + + my $usage_string = xCAT::Usage->parseCommand($command, @exargs); + if ($usage_string) { + $callback->({ data => [$usage_string] }); + $request = {}; + return; + } + + my $parse_result = parse_args($command, $extrargs, $noderange); + if (ref($parse_result) eq 'ARRAY') { + my $error_data; + foreach my $node (@$noderange) { + $error_data .= "\n" if ($error_data); + $error_data .= "$node: Error: " . "$parse_result->[1]"; + } + $callback->({ errorcode => [$parse_result->[0]], data => [$error_data] }); + $request = {}; + return; + } + + my $sn = xCAT::ServiceNodeUtils->get_ServiceNode($noderange, "xcat", "MN"); + foreach my $snkey (keys %$sn) { + my $reqcopy = {%$request}; + $reqcopy->{node} = $sn->{$snkey}; + $reqcopy->{'_xcatdest'} = $snkey; + $reqcopy->{_xcatpreprocessed}->[0] = 1; + push @requests, $reqcopy; + } + + return \@requests; +} + +#------------------------------------------------------- + +=head3 process_request + + Process the command + +=cut + +#------------------------------------------------------- + +sub process_request { + my $request = shift; + $callback = shift; + + if (!xCAT::AGENT::exists_python_agent()) { + xCAT::MsgUtils->message("E", { data => ["The xCAT Python agent does not exist. Check if xCAT-hwctrl-py package is installed on management node and service nodes."] }, $callback); + return; + } + + my $noderange = $request->{node}; + my $check = parse_node_info($noderange); + $callback->({ errorcode => [$check] }) if ($check); + return unless(%node_info); + + my $pid = xCAT::AGENT::start_python_agent(); + if (!defined($pid)) { + xCAT::MsgUtils->message("E", { data => ["Failed to start the xCAT Python agent. Check /var/log/xcat/cluster.log for more information."] }, $callback); + return; + } + + xCAT::AGENT::submit_agent_request($pid, $request, "redfish", \%node_info, $callback); + xCAT::AGENT::wait_agent($pid, $callback); +} + +#------------------------------------------------------- + +=head3 parse_args + + Parse the command line options and operands + +=cut + +#------------------------------------------------------- + +sub parse_args { + my $command = shift; + my $extrargs = shift; + my $noderange = shift; + my $subcommand = undef; + + unless (GetOptions( + 'V|verbose' => \$::VERBOSE, + )) { + return ([ 1, "Error parsing arguments." ]); + } + + if (scalar(@ARGV) != 1 and ($command =~ /rpower/)) { + return ([ 1, "Only one option is supported at the same time for $command" ]); + } else { + $subcommand = $ARGV[0]; + } + + return ([ 1, "Unsupported any command for redfish now" ]); +} + +#------------------------------------------------------- + +=head3 parse_node_info + + Parse the node information: bmc, bmcip, username, password + +=cut + +#------------------------------------------------------- + +sub parse_node_info { + my $noderange = shift; + my $rst = 0; + + my $passwd_table = xCAT::Table->new('passwd'); + my $passwd_hash = $passwd_table->getAttribs({ 'key' => 'redfish' }, qw(username password)); + + my $my_table = xCAT::Table->new('openbmc'); + my $my_hash = $my_table->getNodesAttribs(\@$noderange, ['bmc', 'username', 'password']); + + foreach my $node (@$noderange) { + if (defined($my_hash->{$node}->[0])) { + if ($my_hash->{$node}->[0]->{'bmc'}) { + $node_info{$node}{bmc} = $my_hash->{$node}->[0]->{'bmc'}; + $node_info{$node}{bmcip} = xCAT::NetworkUtils::getNodeIPaddress($my_hash->{$node}->[0]->{'bmc'}); + } + unless($node_info{$node}{bmc}) { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute bmc", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + unless($node_info{$node}{bmcip}) { + xCAT::SvrUtils::sendmsg("Error: Unable to resolve ip address for bmc: $node_info{$node}{bmc}", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + if ($my_hash->{$node}->[0]->{'username'}) { + $node_info{$node}{username} = $my_hash->{$node}->[0]->{'username'}; + } elsif ($passwd_hash and $passwd_hash->{username}) { + $node_info{$node}{username} = $passwd_hash->{username}; + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute username", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + + if ($my_hash->{$node}->[0]->{'password'}) { + $node_info{$node}{password} = $my_hash->{$node}->[0]->{'password'}; + } elsif ($passwd_hash and $passwd_hash->{password}) { + $node_info{$node}{password} = $passwd_hash->{password}; + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get attribute password", $callback, $node); + delete $node_info{$node}; + $rst = 1; + next; + } + } else { + xCAT::SvrUtils::sendmsg("Error: Unable to get information from openbmc table", $callback, $node); + $rst = 1; + next; + } + } + + return $rst; +} + +1;