add the mechanism to auto make document for restapi

This commit is contained in:
daniceexi 2014-03-18 10:22:17 -04:00
parent 707f0c315b
commit a5ff9cfeec
2 changed files with 172 additions and 6 deletions

View File

@ -0,0 +1,128 @@
#! /usr/bin/perl
package genrestapidoc;
my @apigroups = (
{
groupname => 'node',
resources => ['allnode', 'nodeallattr']
},
{
groupname => 'network',
resources => ['network', 'network_allattr', 'network_attr']
},
);
my %formathdl = (
text => \&outtext,
);
sub outtext {
my $def = shift;
my $opt = shift;
my $head = shift;
if ($head) {
print "\n$head\n";
}
my $postfix = "?userName=xxx&password=xxx&pretty=1";
if (defined ($def->{desc})) {
print " $opt - $def->{desc}\n";
}
if (defined ($def->{usage})) {
my @parts = split ('\|', $def->{usage});
if ($parts[1]) {
print " Parameters: $parts[2]\n";
}
if ($parts[2]) {
print " Returns: $parts[2]\n";
}
}
if (defined ($def->{example})) {
my @parts = split ('\|', $def->{example});
print " Example:\n";
if ($parts[1]) {
print " $parts[1]\n";
}
if ($parts[2] && $parts[3] && $parts[4]) {
my ($uri, $data);
if ($part[3] =~ /\s+/) {
($uri, $data) = split(/ /, $part[3]);
print " #curl $parts[2] -k \'https://myserver/xcatws$uri$postfix\' -H Content-Type:application/json --data \'$data\'\n";
} else {
print " #curl $parts[2] -k \'https://myserver/xcatws$parts[3]$postfix\'\n";
}
$parts[4] =~ s/\n/\n /g;
print " $parts[4]\n";
}
}
}
sub gendoc {
my $URIdef = shift;
my $format = shift;
unless ($format) {
$format = "text";
}
my @errmsg;
foreach my $group (@apigroups) {
my $groupname = $group->{'groupname'};
if (defined ($URIdef->{$groupname})) {
foreach my $res (@{$group->{'resources'}}) {
if (defined ($URIdef->{$groupname}->{$res})) {
if (defined ($URIdef->{$groupname}->{$res}->{GET})) {
$formathdl{$format}->($URIdef->{$groupname}->{$res}->{GET}, "GET", $URIdef->{$groupname}->{$res}->{desc});
}
if (defined ($URIdef->{$groupname}->{$res}->{PUT})) {
$formathdl{$format}->($URIdef->{$groupname}->{$res}->{PUT}, "PUT");
}
if (defined ($URIdef->{$groupname}->{$res}->{POST})) {
$formathdl{$format}->($URIdef->{$groupname}->{$res}->{POST}, "POST");
}
if (defined ($URIdef->{$groupname}->{$res}->{DELETE})) {
$formathdl{$format}->($URIdef->{$groupname}->{$res}->{DELETE}, "DELETE");
}
} else {
push @errmsg, "Cannot find the definition for resource [$res]\n";
}
}
} else {
push @errmsg, "Cannot find the definition for resource group [$groupname]\n";
}
}
print @errmsg;
}
sub displayUsage {
foreach my $group (keys %URIdef) {
print "Resource Group: $group\n";
foreach my $res (keys %{$URIdef{$group}}) {
print " Resource: $res\n";
print " $URIdef{$group}->{$res}->{desc}\n";
if (defined ($URIdef{$group}->{$res}->{GET})) {
print " GET: $URIdef{$group}->{$res}->{GET}->{desc}\n";
}
if (defined ($URIdef{$group}->{$res}->{PUT})) {
print " PUT: $URIdef{$group}->{$res}->{PUT}->{desc}\n";
}
if (defined ($URIdef{$group}->{$res}->{POST})) {
print " POST: $URIdef{$group}->{$res}->{POST}->{desc}\n";
}
if (defined ($URIdef{$group}->{$res}->{DELETE})) {
print " DELETE: $URIdef{$group}->{$res}->{DELETE}->{desc}\n";
}
}
}
}

View File

@ -24,6 +24,8 @@ my %URIdef = (
matcher => '^\/node$',
GET => {
desc => "Get all the nodes in xCAT.",
usage => "||An array of node names.|",
example => "|Get all the node names from xCAT database.|GET|/node|[\n all,\n node1,\n node2,\n node3,\n]|",
cmd => "lsdef",
fhandler => \&defhdl,
outhdler => \&defout_remove_appended_type,
@ -34,24 +36,35 @@ my %URIdef = (
matcher => '^\/node\/[^\/]*$',
GET => {
desc => "Get all the attibutes for the node {nodename}.",
usage => "||An array of node objects.|",
example => "|Get all the attibutes for node \'node1\'.|GET|/node/node1|[\n {\n netboot:xnba,\n mgt:1,\n groups:22,\n name:node1,\n postbootscripts:otherpkgs,\n postscripts:syslog,remoteshell,syncfiles\n }\n]|",
cmd => "lsdef",
fhandler => \&defhdl,
outhdler => \&defout,
},
PUT => {
desc => "Change the attibutes for the node {nodename}.",
usage => "||An array of node objects.|",
example => "|Change the attributes mgt=dfm and netboot=yaboot.|PUT|/node/node1 {mgt:dfm,netboot:yaboot}|{\n \"info\":[\n \"1 object definitions have been created or modified.\"\n ]\n}|",
cmd => "chdef",
fhandler => \&defhdl,
outhdler => \&infoout,
},
POST => {
desc => "Create the node {nodename}. DataBody: {attr1:v1,att2:v2...}.",
usage => "||An array of node objects.|",
example => "|Create a node with attributes groups=all, mgt=dfm and netboot=yaboot|POST|/node/node1 {groups:all,mgt:dfm,netboot:yaboot}|{\n \"info\":[\n \"1 object definitions have been created or modified.\"\n ]\n}|",
cmd => "mkdef",
fhandler => \&defhdl,
outhdler => \&infoout,
},
DELETE => {
desc => "Remove the node {nodename}.",
usage => "||An array of node objects.|",
example => "|Delete the node node1|DELETE|/node/node1|{\n \"info\":[\n \"1 object definitions have been removed.\"\n ]\n}|",
cmd => "rmdef",
fhandler => \&defhdl,
outhdler => \&infoout,
},
},
nodeattr => {
@ -631,6 +644,7 @@ my $pageContent = ''; # global var containing the ouptut back to the rest
my $request = {clienttype => 'ws'}; # global var that holds the request to send to xcatd
my $format = 'json';
my $pretty;
my $xmlinstalled;
# Handle the command parameter for debugging and generating doc
my $dbgdata;
@ -639,6 +653,10 @@ sub dbgusage { print "Usage:\n $0 -h\n $0 -d\n $0 {GET|PUT|POST|DELETE}
if ($ARGV[0] eq "-h") {
dbgusage();
exit 0;
} elsif ($ARGV[0] eq "-g") {
require genrestapidoc;
genrestapidoc::gendoc(\%URIdef);
exit 0;
} elsif ($ARGV[0] eq "-d") {
displayUsage();
exit 0;
@ -709,11 +727,7 @@ if ($format eq 'json') {
# 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) {
error('The XML::Simple perl module is missing. Install perl-XML-Simple before using the xCAT REST web services API with this format."}',$STATUS_SERVICE_UNAVAILABLE);
}
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
loadXML();
# Match the first layer of resource URI
my $uriLayer1;
@ -888,6 +902,20 @@ sub defout_remove_appended_type {
}
}
sub infoout {
my $data = shift;
my $json;
foreach my $d (@$data) {
if (defined ($d->{info})) {
push @{$json->{info}}, @{$d->{info}};
}
}
if ($json) {
addPageContent($JSON->encode($json));
}
}
sub actionout {
my $data = shift;
my $param =shift;
@ -1130,7 +1158,6 @@ sub displayUsage {
}
# This handles and removes serverdone and error tags in the perl data structure that is from the xml that xcatd returned
#bmp: is there a way to avoid make a copy of the whole response? For big output that could be time consuming.
# For the error tag, you don't have to bother copying the response, because you are going to exit anyway.
@ -1484,6 +1511,17 @@ sub fetchParameters {
return ($genparms, $phash);
}
# Load the XML::Simple module
sub loadXML {
if ($xmlinstalled) { return; }
$xmlinstalled = eval { require XML::Simple; };
unless ($xmlinstalled) {
error('The XML::Simple perl module is missing. Install perl-XML-Simple before using the xCAT REST web services API with this format."}',$STATUS_SERVICE_UNAVAILABLE);
}
$XML::Simple::PREFERRED_PARSER = 'XML::Parser';
}
# Load the JSON perl module, if not already loaded. Sets the $JSON global var.
sub loadJSON {
if ($JSON) { return; } # already loaded