example rest apis working with new json structure
This commit is contained in:
parent
aea43684c3
commit
e251f0a2cf
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env perl
|
||||
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
# This is a command which can be used to access the rest api of xCAT
|
||||
|
||||
@ -19,6 +19,10 @@ my $usage_string = "Usage:
|
||||
-f The output format of the requested action
|
||||
-V Display the verbose message\n";
|
||||
|
||||
#todo: make the code below into functions so that this file can be used for 2 purposes:
|
||||
# 1. contain all the test cases that can all be run at once
|
||||
# 2. if arguments are passed in, run the one api call passed in
|
||||
|
||||
# Parse the argument
|
||||
$Getopt::Long::ignorecase = 0;
|
||||
Getopt::Long::Configure( "bundling" );
|
||||
|
@ -1,41 +1,30 @@
|
||||
#!/bin/bash
|
||||
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
# * test & doc all current calls
|
||||
# - finish test driver (both curl and natively from perl)
|
||||
# * add debugging and fix bugs
|
||||
# - change xdsh/xdcp to post and compact that code
|
||||
# - change format of all put and post calls
|
||||
# - change structure of output json and add Returns lines to doc
|
||||
# - add nodeset stat
|
||||
# - change table routines to use lissa's xml interface and doc them as an alternative to the node def calls
|
||||
# - add: osimage def create, change, delete and copycds (bai yuan)
|
||||
# - eliminate pw in url - api key or certificates (bai yuan)
|
||||
# - send output back to client as it comes from xcatd, and compare code to Client.pm (bai yuan)
|
||||
# - is the data sent back given the correct Content/Type? (bai yuan)
|
||||
# - test, fix, doc the other resource handlers in there: groups, logs, notifications, policies, accounts, hypervisor(bai yuan)
|
||||
# - do perf/scale tests and optimize code, incl breaking resource handlers into separate pms
|
||||
# - return metadata of resources (list of possible attributes of def objects)(bai yuan)
|
||||
# Test driver for xcatws.cgi
|
||||
|
||||
userpw = 'userName=bp&password=bryan1'
|
||||
format = 'format=xml'
|
||||
user = ''
|
||||
pw = ''
|
||||
format = 'format=json&pretty=1'
|
||||
|
||||
#curl -X GET -k 'http://127.0.0.1/xcatws/nodes?userName=bp&password=bryan1&format=xml'
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/nodes?userName=bp&password=bryan1&format=xml'
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/nodes?userName=bp&password=bryan1&format=xml&field=mac'
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/nodes/test001-test006?userName=bp&password=bryan1&format=xml'
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/nodes/test001-test006?userName=bp&password=bryan1&format=xml&field=mac'
|
||||
#curl -X PUT -k --data '{"room":"foo"}' 'https://127.0.0.1/xcatws/nodes/test001?userName=bp&password=bryan1'
|
||||
#curl -X POST -k --data '{"groups":"compute,all"}' 'https://127.0.0.1/xcatws/nodes/test001?userName=bp&password=bryan1'
|
||||
curl -X DELETE -k 'http://127.0.0.1/xcatws/nodes/test001?userName=bp&password=bryan1'
|
||||
curl -X PUT -k 'https://127.0.0.1/xcatws/nodes/test001?userName=bp&password=bryan1&format=xml&debug=0' -H Content-Type:application/json --data '{"room":"hi","unit":"7"}'
|
||||
curl -X POST -k 'https://127.0.0.1/xcatws/nodes/ws1?userName=bp&password=bryan1&format=xml&debug=0' -H Content-Type:application/json --data '{"groups":"wstest"}'
|
||||
#todo: add a test case for every api call that is documented
|
||||
#todo: figure out why i currently have to specify -k
|
||||
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/groups?userName=bp&password=bryan1&format=xml'
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/nodes?userName=$user&password=$pw&format=xml"
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/nodes?userName=$user&password=$pw&format=xml&field=mac"
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/nodes/test001-test006?userName=$user&password=$pw&format=xml"
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/nodes/test001-test006?userName=$user&password=$pw&format=xml&field=mac"
|
||||
curl -X DELETE -k "http://127.0.0.1/xcatws/nodes/test001?userName=$user&password=$pw"
|
||||
curl -X PUT -k "https://127.0.0.1/xcatws/nodes/test001?userName=$user&password=$pw&format=xml&debug=0" -H Content-Type:application/json --data '{"room":"hi","unit":"7"}'
|
||||
curl -X POST -k "https://127.0.0.1/xcatws/nodes/ws1?userName=$user&password=$pw&format=xml&debug=0" -H Content-Type:application/json --data '{"groups":"wstest"}'
|
||||
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/images?userName=bp&password=bryan1&format=xml'
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/images?userName=bp&password=bryan1&format=xml&field=osvers'
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/images/bp-netboot?userName=bp&password=bryan1&format=xml'
|
||||
curl -X GET -k 'https://127.0.0.1/xcatws/images/bp-netboot?userName=bp&password=bryan1&format=xml&field=osvers'
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/groups?userName=$user&password=$pw&format=xml"
|
||||
|
||||
./xcatws-test.pl -u "https://127.0.0.1/xcatws/nodes/test001?userName=bp&password=bryan1" -m GET
|
||||
./xcatws-test.pl -u "https://127.0.0.1/xcatws/nodes/test001?userName=bp&password=bryan1" -m PUT "nodepos.room=foo"
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/images?userName=$user&password=$pw&format=xml"
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/images?userName=$user&password=$pw&format=xml&field=osvers"
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/images/bp-netboot?userName=$user&password=$pw&format=xml"
|
||||
curl -X GET -k "https://127.0.0.1/xcatws/images/bp-netboot?userName=$user&password=$pw&format=xml&field=osvers"
|
||||
|
||||
#todo: remove when these test cases are in xcatws-test.pl
|
||||
./xcatws-test.pl -u "https://127.0.0.1/xcatws/nodes/test001?userName=$user&password=$pw" -m GET
|
||||
./xcatws-test.pl -u "https://127.0.0.1/xcatws/nodes/test001?userName=$user&password=$pw" -m PUT "nodepos.room=foo"
|
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
# IBM(c) 2014 EPL license http://www.eclipse.org/legal/epl-v10.html
|
||||
use strict;
|
||||
use CGI qw/:standard/; #todo: remove :standard when the code only uses object oriented interface
|
||||
use JSON; #todo: require this dynamically later on so that installations that do not use xcatws.cgi do not need perl-JSON
|
||||
@ -16,7 +17,7 @@ use xCAT::Table;
|
||||
# ScriptAlias /xcatws /var/www/cgi-bin/xcatws.cgi
|
||||
# - also upgraded CGI to 3.52
|
||||
# - If "Internal Server Error" is returned, look at /var/log/httpd/ssl_error_log
|
||||
# -can run your cgi script from the cli: http://perldoc.perl.org/CGI.html#DEBUGGING
|
||||
# - can run your cgi script from the cli: http://perldoc.perl.org/CGI.html#DEBUGGING
|
||||
|
||||
# This is how the parameters come in:
|
||||
# GET: url parameters come $q->url_param. There is no put/post data.
|
||||
@ -78,7 +79,7 @@ if ($DEBUGGING) {
|
||||
#if (defined($q->param('PUTDATA')) || defined($q->param('POSTDATA'))) {
|
||||
# addPageContent("put data 1 " . $q->p($q->param('PUTDATA') . "\n"));
|
||||
#} elsif (isPut()) {
|
||||
# my $entries = JSON::decode_json($q->param('PUTDATA'));
|
||||
# my $entries = $JSON->decode($q->param('PUTDATA'));
|
||||
# if (scalar(@$entries) >= 1) {
|
||||
# addPageContent("put data 2 \n");
|
||||
# foreach (@$entries) {
|
||||
@ -129,31 +130,33 @@ my %formatters = (
|
||||
|
||||
|
||||
# puts $queryString into %queryHash
|
||||
fetchParameter($queryString); #todo: remove when not used anymore
|
||||
fetchParameter($queryString); #todo: stop using and then remove when not used anymore
|
||||
|
||||
if (!exists $formatters{$format}) {
|
||||
addPageContent("The format '$format' is not supported");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
my $JSON; # global ptr to the json object
|
||||
if ($format eq 'json' || isPut() || isPost()) {
|
||||
# require JSON dynamically and let them know if it is not installed
|
||||
my $jsoninstalled = eval { require JSON; };
|
||||
unless ($jsoninstalled) {
|
||||
addPageContent('{"data":"JSON perl module missing. Install perl-JSON before using the xCAT REST web services API."}');
|
||||
sendResponseMsg($STATUS_SERVICE_UNAVAILABLE);
|
||||
error("JSON perl module missing. Install perl-JSON before using the xCAT REST web services API.", $STATUS_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
$JSON = JSON->new();
|
||||
if ($q->url_param('pretty')) { $JSON->indent(1); }
|
||||
}
|
||||
if ($format eq 'xml') {
|
||||
# require XML dynamically and let them know if it is not installed
|
||||
my $xmlinstalled = eval { require XML::Simple; };
|
||||
unless ($xmlinstalled) {
|
||||
addPageContent('The XML::Simple perl module is missing. Install perl-XML-Simple before using the xCAT REST web services API with this format."}');
|
||||
sendResponseMsg($STATUS_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
|
||||
#debugandexit('here');
|
||||
|
||||
# require XML dynamically and let them know if it is not installed
|
||||
# we need XML all the time to send request to xcat, even if thats not the return format requested by the user
|
||||
my $xmlinstalled = eval { require XML::Simple; };
|
||||
unless ($xmlinstalled) {
|
||||
addPageContent('The XML::Simple perl module is missing. Install perl-XML-Simple before using the xCAT REST web services API with this format."}');
|
||||
sendResponseMsg($STATUS_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
|
||||
#debugandexit('here');
|
||||
|
||||
#resource handlers
|
||||
my %resources = (
|
||||
@ -190,7 +193,7 @@ if ($pathInfo =~ /^\/$/ || $pathInfo =~ /^$/) {
|
||||
my $formatType; # global var for tablesHandler to pass the splitCommas option to wrapHtml
|
||||
|
||||
#general tests for valid requests and responses with HTTP codes here
|
||||
if (!doesResourceExist($resource)) {
|
||||
if (!exists($resources{$resource})) {
|
||||
addPageContent("Resource '$resource' does not exist");
|
||||
sendResponseMsg($STATUS_NOT_FOUND); # this will also exit
|
||||
}
|
||||
@ -235,8 +238,7 @@ sub nodesHandler {
|
||||
if (defined $path[2]) {
|
||||
$subResource = $path[2];
|
||||
unless (defined($noderange)) {
|
||||
addPageContent("Invalid nodes and/or groups in noderange");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
error("Invalid nodes and/or groups in noderange",$STATUS_BAD_REQUEST);
|
||||
}
|
||||
$request->{noderange} = $noderange;
|
||||
|
||||
@ -284,8 +286,7 @@ sub nodesHandler {
|
||||
}
|
||||
}
|
||||
else {
|
||||
addPageContent("Unspported operation on nodes object.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
error("Unspported operation on nodes object.",$STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -311,31 +312,17 @@ sub nodesHandler {
|
||||
my $entrydata;
|
||||
|
||||
unless (defined($noderange)) {
|
||||
addPageContent("Invalid nodes and/or groups in noderange");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
error("Invalid nodes and/or groups in noderange",$STATUS_BAD_REQUEST);
|
||||
}
|
||||
$request->{noderange} = $noderange;
|
||||
|
||||
unless ($q->param('PUTDATA')) {
|
||||
#temporary allowance for the put data to be contained in the queryString
|
||||
# unless ($queryhash{'putData'}) {
|
||||
addPageContent("No set attribute was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
# }
|
||||
# else {
|
||||
# foreach my $put (@{$queryhash{'putData'}}) {
|
||||
# debug("put=$put");
|
||||
# my ($key, $value) = split(/=/, $put, 2);
|
||||
# if ($key eq 'field' && $value) {
|
||||
# push @entries, $value;
|
||||
# }
|
||||
# }
|
||||
# }
|
||||
error("No set attribute was supplied.",$STATUS_BAD_REQUEST);
|
||||
}
|
||||
else {
|
||||
# decode_json returns a reference to an array or hash
|
||||
$entries = eval { JSON::decode_json($q->param('PUTDATA')); };
|
||||
if ($@) { addPageContent ("$@"); sendResponseMsg($STATUS_BAD_REQUEST); }
|
||||
$entries = eval { $JSON->decode($q->param('PUTDATA')); };
|
||||
if ($@) { error("$@",$STATUS_BAD_REQUEST); }
|
||||
debug("entries=" . Dumper($entries));
|
||||
#if (scalar(@entries) < 1) {
|
||||
# addPageContent("No set attribute was supplied.");
|
||||
@ -365,8 +352,7 @@ sub nodesHandler {
|
||||
extractData(\%elements, @$entries);
|
||||
|
||||
unless (scalar(%elements)) {
|
||||
addPageContent("No power operands were supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
error("No power operands were supplied.",$STATUS_BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
elsif ($subResource eq "energy") {
|
||||
@ -503,20 +489,15 @@ sub nodesHandler {
|
||||
push @args, $elements{'target'};
|
||||
}
|
||||
}
|
||||
else { msg('error',"unsupported node resource $subResource."); sendResponseMsg($STATUS_BAD_REQUEST); }
|
||||
else { error("unsupported node resource $subResource.", $STATUS_BAD_REQUEST); }
|
||||
}
|
||||
else { # setting node attributes in the db
|
||||
#my %elements;
|
||||
#my $name;
|
||||
#my $val;
|
||||
|
||||
#$request->{command} = "tabch";
|
||||
#push @args, "node=" . $request->{noderange};
|
||||
#todo: change this to use lissa's routines
|
||||
$request->{command} = "chdef";
|
||||
push @args, "-t", "node";
|
||||
push @args, "-o", $request->{noderange};
|
||||
|
||||
#extractData(\%elements, @entries);
|
||||
# input is a json object with key/value pairs
|
||||
while (my ($name, $val) = each (%$entries)) {
|
||||
push @args, $name . "=" . $val;
|
||||
}
|
||||
@ -527,22 +508,21 @@ sub nodesHandler {
|
||||
push @args, "-t", "node";
|
||||
|
||||
unless (defined($noderange)) {
|
||||
addPageContent("No nodename was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
error("No nodename was supplied.",$STATUS_BAD_REQUEST);
|
||||
}
|
||||
|
||||
push @args, "-o", $noderange;
|
||||
|
||||
if ($q->param('POSTDATA')) {
|
||||
# decode_json returns a reference to an array or hash
|
||||
my $entries = eval { JSON::decode_json($q->param('POSTDATA')); };
|
||||
if ($@) { addPageContent ("$@"); sendResponseMsg($STATUS_BAD_REQUEST); }
|
||||
my $entries = eval { $JSON->decode($q->param('POSTDATA')); };
|
||||
if ($@) { error("$@",$STATUS_BAD_REQUEST); }
|
||||
debug("entries=" . Dumper($entries));
|
||||
while (my ($name, $val) = each (%$entries)) {
|
||||
push @args, $name . "=" . $val;
|
||||
}
|
||||
}
|
||||
else { msg('error', 'no post data given.'); sendResponseMsg($STATUS_BAD_REQUEST); }
|
||||
else { error('no post data given.', $STATUS_BAD_REQUEST); }
|
||||
}
|
||||
elsif (isDelete()) {
|
||||
|
||||
@ -550,14 +530,12 @@ sub nodesHandler {
|
||||
$request->{command} = 'rmdef';
|
||||
push @args, "-t", "node";
|
||||
unless (defined($noderange)) {
|
||||
addPageContent("No nodename was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
error("No nodename was supplied.",$STATUS_BAD_REQUEST);
|
||||
}
|
||||
push @args, "-o", $noderange;
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -668,7 +646,6 @@ sub groupsHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -715,7 +692,7 @@ sub imagesHandler {
|
||||
addPageContent("Invalid Parameters");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
}
|
||||
$entries = JSON::decode_json($q->param('POSTDATA'));
|
||||
$entries = $JSON->decode($q->param('POSTDATA'));
|
||||
if (scalar(@$entries) < 1) {
|
||||
addPageContent("No set attribute was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
@ -864,7 +841,6 @@ sub imagesHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -966,7 +942,6 @@ sub logsHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1043,7 +1018,6 @@ sub monitorsHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1102,10 +1076,10 @@ sub networksHandler {
|
||||
push @{$request->{arg}}, '-t', 'network', '-o', $netname;
|
||||
|
||||
if (defined($q->param('PUTDATA'))) {
|
||||
$entries = JSON::decode_json($q->param('PUTDATA'));
|
||||
$entries = $JSON->decode($q->param('PUTDATA'));
|
||||
}
|
||||
elsif (defined($q->param('POSTDATA'))) {
|
||||
$entries = JSON::decode_json($q->param('POSTDATA'));
|
||||
$entries = $JSON->decode($q->param('POSTDATA'));
|
||||
}
|
||||
else {
|
||||
addPageContent("No Field and Value map was supplied.");
|
||||
@ -1135,7 +1109,6 @@ sub networksHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit(0);
|
||||
}
|
||||
@responses = sendRequest(genRequest());
|
||||
|
||||
@ -1214,7 +1187,6 @@ sub notificationsHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1313,7 +1285,6 @@ sub policiesHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1360,7 +1331,7 @@ sub siteHandler {
|
||||
}
|
||||
} else {
|
||||
if ($q->param('PUTDATA')) {
|
||||
my $entries = JSON::decode_json($q->param('PUTDATA'));
|
||||
my $entries = $JSON->decode($q->param('PUTDATA'));
|
||||
foreach (@$entries) {
|
||||
push @{$request->{arg}}, $_;
|
||||
}
|
||||
@ -1439,7 +1410,7 @@ sub tablesHandler {
|
||||
}
|
||||
}
|
||||
else {
|
||||
$entries = JSON::decode_json($q->param('PUTDATA'));
|
||||
$entries = $JSON->decode($q->param('PUTDATA'));
|
||||
if (scalar(@$entries) < 1) {
|
||||
addPageContent("No set attribute was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
@ -1488,7 +1459,6 @@ sub tablesHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1619,7 +1589,6 @@ sub accountsHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1788,7 +1757,6 @@ sub objectsHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1847,7 +1815,7 @@ sub vmsHandler {
|
||||
}
|
||||
|
||||
#collect all parameters from the postdata
|
||||
my $entries = JSON::decode_json($q->param('POSTDATA'));
|
||||
my $entries = $JSON->decode($q->param('POSTDATA'));
|
||||
if (scalar(@$entries) < 1) {
|
||||
addPageContent("No set attribute was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
@ -1939,7 +1907,7 @@ sub vmsHandler {
|
||||
elsif (isPut()) {
|
||||
$request->{command} = 'chvm';
|
||||
if ($q->param('PUTDATA')) {
|
||||
my $entries = JSON::decode_json($q->param('PUTDATA'));
|
||||
my $entries = $JSON->decode($q->param('PUTDATA'));
|
||||
if (scalar(@$entries) < 1) {
|
||||
addPageContent("No Field and Value map was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
@ -1965,7 +1933,6 @@ sub vmsHandler {
|
||||
}
|
||||
else {
|
||||
unsupportedRequestType();
|
||||
exit();
|
||||
}
|
||||
|
||||
push @{$request->{arg}}, @args;
|
||||
@ -1999,7 +1966,7 @@ sub hypervisorHandler {
|
||||
else {
|
||||
$request->{command} = 'chhypervisor';
|
||||
}
|
||||
my $entries = JSON::decode_json( $q->param('PUTDATA') );
|
||||
my $entries = $JSON->decode( $q->param('PUTDATA') );
|
||||
if (scalar(@$entries) < 1) {
|
||||
addPageContent("No set attribute was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
@ -2029,7 +1996,7 @@ sub debugHandler {
|
||||
$request->{command} = 'xcatclientnnr xcatdebug';
|
||||
|
||||
#push @args, 'xcatdebug';
|
||||
my $entries = JSON::decode_json( $q->param('PUTDATA') );
|
||||
my $entries = $JSON->decode( $q->param('PUTDATA') );
|
||||
if (scalar(@$entries) < 1) {
|
||||
addPageContent("No set attribute was supplied.");
|
||||
sendResponseMsg($STATUS_BAD_REQUEST);
|
||||
@ -2058,15 +2025,17 @@ sub debugandexit {
|
||||
sendResponseMsg($STATUS_OK);
|
||||
}
|
||||
|
||||
# add a msg to the output in the correct format
|
||||
sub msg {
|
||||
my ($severity, $str) = @_;
|
||||
if (!$severity) { $severity = 'info'; }
|
||||
# add a error msg to the output in the correct format and end this request
|
||||
#todo: replace all addPageContent/sendResponseMsg pairs to call this function instead
|
||||
sub error {
|
||||
my ($msg, $errorcode) = @_;
|
||||
my $severity = 'error';
|
||||
my $m;
|
||||
if ($format eq 'xml') { $m = "<$severity>$str</$severity>\n"; }
|
||||
elsif ($format eq 'json') { $m = qq({"$severity":"$str"}\n); }
|
||||
else { $m = "<p>$severity: $str</p>\n"; }
|
||||
if ($format eq 'xml') { $m = "<$severity>$msg</$severity>\n"; }
|
||||
elsif ($format eq 'json') { $m = qq({"$severity":"$msg"}\n); }
|
||||
else { $m = "<p>$severity: $msg</p>\n"; }
|
||||
addPageContent($m);
|
||||
sendResponseMsg($errorcode);
|
||||
}
|
||||
|
||||
# Append content to the global var holding the output to go back to the rest client
|
||||
@ -2081,15 +2050,9 @@ sub addPageContent {
|
||||
sub sendResponseMsg {
|
||||
my $code = shift;
|
||||
my $tempFormat = '';
|
||||
if ('json' eq $format) {
|
||||
$tempFormat = 'application/json';
|
||||
}
|
||||
elsif ('xml' eq $format) {
|
||||
$tempFormat = 'text/xml';
|
||||
}
|
||||
else {
|
||||
$tempFormat = 'text/html';
|
||||
}
|
||||
if ('json' eq $format) { $tempFormat = 'application/json'; }
|
||||
elsif ('xml' eq $format) { $tempFormat = 'text/xml'; }
|
||||
else { $tempFormat = 'text/html'; }
|
||||
print $q->header(-status => $code, -type => $tempFormat);
|
||||
print $pageContent;
|
||||
exit(0);
|
||||
@ -2108,12 +2071,8 @@ sub genRequest {
|
||||
my $xml = XML::Simple::XMLout($request, RootName => 'xcatrequest', NoAttr => 1, KeyAttr => []);
|
||||
}
|
||||
|
||||
sub doesResourceExist {
|
||||
my $res = shift;
|
||||
return exists $resources{$res};
|
||||
}
|
||||
|
||||
#when use put and post, can not fetch the url-parameter, so add this sub to support all kinds of methods
|
||||
# when use put and post, can not fetch the url-parameter, so add this sub to support all kinds of methods
|
||||
#todo: stop using this. Can always get parms thru $q->url_param, regardless of the request type
|
||||
sub fetchParameter {
|
||||
my $parstr = shift;
|
||||
unless ($parstr) {
|
||||
@ -2130,7 +2089,7 @@ sub fetchParameter {
|
||||
}
|
||||
|
||||
# Extract the put data or post data into the hash that is passed in by reference.
|
||||
# The data (2nd parameter) comes from JSON::decode_json()
|
||||
# The data (2nd parameter) comes from $JSON->decode()
|
||||
#todo: remove when not used any more
|
||||
sub extractData {
|
||||
my $returnhash = shift;
|
||||
@ -2167,17 +2126,16 @@ sub wrapData {
|
||||
#trim the serverdone message off
|
||||
if (exists $data->[0]->{serverdone} && exists $data->[0]->{error}) {
|
||||
$errorInformation = $data->[0]->{error}->[0];
|
||||
addPageContent($q->p($errorInformation));
|
||||
addPageContent($q->p($errorInformation)); #todo: put this in the requested format?
|
||||
if (($errorInformation =~ /Permission denied/) || ($errorInformation =~ /Authentication failure/)) {
|
||||
sendResponseMsg($STATUS_UNAUTH);
|
||||
}
|
||||
else {
|
||||
sendResponseMsg($STATUS_FORBIDDEN);
|
||||
}
|
||||
exit 1;
|
||||
}
|
||||
else {
|
||||
pop @{$data};
|
||||
pop @{$data}; #todo: are we sure this is the serverdone entry?
|
||||
}
|
||||
|
||||
# Call the appropriate formatting function stored in the formatters hash
|
||||
@ -2185,7 +2143,7 @@ sub wrapData {
|
||||
$formatters{$format}->($data);
|
||||
}
|
||||
|
||||
# all output has been added into the global varibale pageContent, call the response funcion
|
||||
# all output has been added into the global varibale pageContent, now complete the response to the user
|
||||
if (exists $data->[0]->{info} && $data->[0]->{info}->[0] =~ /Could not find an object/) {
|
||||
sendResponseMsg($STATUS_NOT_FOUND);
|
||||
}
|
||||
@ -2197,25 +2155,89 @@ sub wrapData {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Structure the response perl data structure into well-formed json. Since the structure of the
|
||||
# xml output that comes from xcatd is inconsistent and not very structured, we have a lot of work to do.
|
||||
sub wrapJson {
|
||||
# this is an array of responses from xcatd. Often all the output comes back in 1 response, but not always.
|
||||
my $data = shift;
|
||||
|
||||
# put, post, and delete usually just give a short msg, if anything
|
||||
if (isPut() || isPost() || isDelete() || isPatch()) {
|
||||
addPageContent($JSON->encode($data));
|
||||
return;
|
||||
}
|
||||
|
||||
# Divide the processing into several groups of requests, according to how they return the output
|
||||
# At this point, these are all gets
|
||||
my $json;
|
||||
$json->{'data'} = $data;
|
||||
addPageContent(JSON::to_json($json));
|
||||
if ($resource eq 'nodes') {
|
||||
if (!defined $path[2]) { # querying node attributes
|
||||
# The data structure is: array of hashes that have a single key 'info'. The value for that key
|
||||
# is an array of lines of lsdef output (all nodes in the same array).
|
||||
# Create a json array of node objects. Each node object contains the attributes/values (including
|
||||
# the nodename) of that object.
|
||||
$json = [];
|
||||
foreach my $d (@$data) {
|
||||
my $jsonnode;
|
||||
my $lines = $d->{info};
|
||||
foreach my $l (@$lines) {
|
||||
if ($l =~ /^Object name: /) { # start new node
|
||||
if (defined($jsonnode)) { push @$json, $jsonnode; } # push previous object onto array
|
||||
my ($nodename) = $l =~ /^Object name:\s+(\S+)/;
|
||||
$jsonnode = { nodename => $nodename };
|
||||
}
|
||||
else { # just an attribute of the current node
|
||||
if (!defined($jsonnode)) { error('improperly formatted lsdef output from xcatd', $STATUS_TEAPOT); }
|
||||
my ($attr, $val) = $l =~ /^\s*(\S+)=(.*)$/;
|
||||
if (!defined($attr)) { error('improperly formatted lsdef output from xcatd', $STATUS_TEAPOT); }
|
||||
$jsonnode->{$attr} = $val;
|
||||
}
|
||||
}
|
||||
if (defined($jsonnode)) { push @$json, $jsonnode; $jsonnode=undef; } # push last object onto array
|
||||
}
|
||||
addPageContent($JSON->encode($json));
|
||||
}
|
||||
elsif (grep(/^$path[2]$/, qw(power inventory vitals energy))) { # querying other node info
|
||||
# The data structure is: array of hashes that have a single key 'node'. The value for that key
|
||||
# is a 1-element array that has a hash with keys 'name' and 'data'. The 'name' value is a 1-element
|
||||
# array that has the nodename. The 'data' value is a 1-element array of a hash that has keys 'desc'
|
||||
# and 'content' (sometimes desc is ommited).
|
||||
# Create a json array of node objects. Each node object contains the attributes/values (including
|
||||
# the nodename) of that object.
|
||||
$json = {}; # its keys are nodenames
|
||||
foreach my $d (@$data) {
|
||||
# each element is a complex structure that contains 1 attr and value for a node
|
||||
my $node = $d->{node}->[0];
|
||||
my $nodename = $node->{name}->[0];
|
||||
my $nodedata = $node->{data}->[0];
|
||||
my $contents = $nodedata->{contents}->[0];
|
||||
my $desc = 'power'; # rpower doesn't output a desc tag
|
||||
if (defined($nodedata->{desc})) { $desc = $nodedata->{desc}->[0]; }
|
||||
|
||||
# add this desc and content into this node's hash
|
||||
$json->{$nodename}->{$desc} = $contents;
|
||||
}
|
||||
# convert this hash of hashes into an array of hashes
|
||||
my @jsonarray;
|
||||
foreach my $n (sort(keys(%$json))) {
|
||||
$json->{$n}->{nodename} = $n; # add the key (nodename) inside of the node's hash
|
||||
push @jsonarray, $json->{$n};
|
||||
}
|
||||
addPageContent($JSON->encode(\@jsonarray));
|
||||
}
|
||||
else { # querying a node subresource (rpower, rvitals, rinv, etc.)
|
||||
addPageContent($JSON->encode($data));
|
||||
} # end else path[2] defined
|
||||
} # end if nodes
|
||||
}
|
||||
|
||||
sub wrapHtml {
|
||||
my $item;
|
||||
my $response = shift;
|
||||
#my $baseUri = $url . $pathInfo;
|
||||
#if ($baseUri !~ /\/^/) {
|
||||
# $baseUri .= "/";
|
||||
#}
|
||||
|
||||
foreach my $element (@$response) {
|
||||
|
||||
#foreach my $element (@$data){
|
||||
#if($element->{error}){
|
||||
if ($element->{node}) {
|
||||
addPageContent("<table border=1>");
|
||||
foreach $item (@{$element->{node}}) {
|
||||
@ -2351,12 +2373,10 @@ sub sendRequest {
|
||||
}
|
||||
unless ($client) {
|
||||
if ($@ =~ /SSL Timeout/) {
|
||||
addPageContent("Connection failure: SSL Timeout or incorrect certificates in ~/.xcat");
|
||||
sendResponseMsg($STATUS_TIMEOUT);
|
||||
error("Connection failure: SSL Timeout or incorrect certificates in ~/.xcat",$STATUS_TIMEOUT);
|
||||
}
|
||||
else {
|
||||
addPageContent("Connection failurexx: $@");
|
||||
sendResponseMsg($STATUS_SERVICE_UNAVAILABLE);
|
||||
error("Connection failurexx: $@",$STATUS_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2401,9 +2421,7 @@ sub sendRequest {
|
||||
}
|
||||
}
|
||||
unless ($cleanexit) {
|
||||
addPageContent("ERROR/WARNING: communication with the xCAT server seems to have been ended prematurely");
|
||||
sendResponseMsg($STATUS_SERVICE_UNAVAILABLE);
|
||||
exit(0);
|
||||
error("communication with the xCAT server seems to have been ended prematurely",$STATUS_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
if ($DEBUGGING) {
|
||||
@ -2436,6 +2454,5 @@ sub isAuthenticUser {
|
||||
}
|
||||
|
||||
#authentication failure
|
||||
addPageContent($responses[0]->{error}[0]);
|
||||
sendResponseMsg($STATUS_UNAUTH);
|
||||
error($responses[0]->{error}[0], $STATUS_UNAUTH);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user