add the mechanism to auto make document for restapi
This commit is contained in:
		
							
								
								
									
										128
									
								
								xCAT-server/xCAT-wsapi/genrestapidoc.pm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										128
									
								
								xCAT-server/xCAT-wsapi/genrestapidoc.pm
									
									
									
									
									
										Executable 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"; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user