diff --git a/xCAT-wsapi/xcatws.cgi b/xCAT-wsapi/xcatws.cgi
deleted file mode 100755
index 1c3e9082d..000000000
--- a/xCAT-wsapi/xcatws.cgi
+++ /dev/null
@@ -1,1607 +0,0 @@
-#!/usr/bin/perl
-use strict;
-use CGI qw/:standard/;
-use JSON;
-use Data::Dumper;
-
-#added the line:
-#ScriptAlias /xcatws /var/www/cgi-bin/xcatws.cgi
-#to /etc/httpd/conf/httpd.conf to hid the cgi-bin and .cgi extension in the uri
-#
-# also upgraded CGI to 3.52
-
-#take the JSON or XML and put it into a data structure
-#all data input will be done from the common structure
-
-#turn on or off the debugging output
-my $DEBUGGING = 1;
-
-my $q = CGI->new;
-my $url = $q->url;
-my $pathInfo = $q->path_info;
-my $requestType = $ENV{'REQUEST_METHOD'};
-my $queryString = $ENV{'QUERY_STRING'};
-my @path = split(/\//, $pathInfo);
-shift(@path);
-my $resource = $path[0];
-print $q->header('text/html');
-my $request = {clienttype =>'ws'};
-
-#error status codes
-my $STATUS_BAD_REQUEST = "400 Bad Request";
-my $STATUS_UNAUTH = "401 Unauthorized";
-my $STATUS_FORBIDDEN = "403 Forbidden";
-my $STATUS_NOT_FOUND= "404 Not Found";
-my $STATUS_NOT_ALLOWED = "405 Method Not Allowed";
-my $STATUS_NOT_ACCEPTABLE = "406 Not Acceptable";
-my $STATUS_TIMEOUT = "408 Request Timeout";
-my $STATUS_EXPECT_FAILED = "417 Expectation Failed";
-my $STATUS_TEAPOT = "418 I'm a teapot";
-my $STATUS_SERVICE_UNAVAILABLE = "503 Service Unavailable";
-
-#good status codes
-my $STATUS_OK = "200 OK";
-my $STATUS_CREATED = "201 Created";
-
-sub sendStatusMsg{
- my $code = shift;
- my $message = shift;
- print $q->header(-status => $code);
- print $message;
-}
-
-sub unsupportedRequestType{
- sendStatusMsg($STATUS_NOT_ALLOWED, "request method '$requestType' is not supported on resource '$resource'");
-}
-
-use XML::Simple;
-$XML::Simple::PREFERRED_PARSER='XML::Parser';
-
-sub genRequest{
- if($DEBUGGING){
- print $q->p("request ".Dumper($request));
- }
- my $xml = XMLout($request, RootName=>'xcatrequest',NoAttr=>1,KeyAttr=>[]);
-}
-
-#default format
-my $format = 'html';
-
-#data formatters. To add one simple copy the format of an existing one
-# and add it to this hash
-my %formatters = ('html' => \&wrapHtml,
- 'json' => \&wrapJson,
- 'xml' => \&wrapXml,
- );
-
-if($q->param('format'))
-{
- $format = $q->param('format');
- if(!exists $formatters{$format}){
- sendStatusMsg($STATUS_BAD_REQUEST, "The format '$format' is not valid");
- exit(0);
- }
-}
-
-#if no resource was specified
-if($pathInfo =~ /^\/$/ || $pathInfo =~ /^$/){
- print $q->p('Some general xCAT WS page will be served or forwarded to when there is no resource specified');
- exit(0);
-}
-
-
-my $XCAT_PATH = '/opt/xcat/bin';
-
-my %resources = (groups => \&groupsHandler,
- images => \&imagesHandler,
- logs => \&logsHandler,
- monitors => \&monitorsHandler,
- networks => \&networksHandler,
- nodes => \&nodesHandler,
- notifications => \¬ificationsHandler,
- policies => \&policiesHandler,
- site => \&siteHandler,
- tables => \&tablesHandler,
- accounts => \&accountsHandler,
- objects => \&objectsHandler,
- vms => \&vmsHandler);
-
-sub doesResourceExist
-{
- my $res = shift;
- return exists $resources{$res};
-}
-
-if($DEBUGGING){
- if(defined $q->param('PUTDATA')){
- print "put data ".$q->p($q->param('PUTDATA')."\n");
- }
- if(defined $q->param('POSTDATA')){
- print "post data ".$q->p($q->param('POSTDATA')."\n");
- }
- print $q->p("Parameters ");
- my @params = $q->param;
- foreach (@params)
- {
- print "$_ = ".$q->param($_)."\n";
- }
- print $q->p("Query String $queryString"."\n");
- print $q->p("HTTP Method $requestType"."\n");
- print $q->p("URI $url"."\n");
- print $q->p("path ".Dumper(@path)."\n");
-}
-
-my $userName;
-my $password;
-
-sub handleRequest{
- if(defined $q->param('userName')){
- $userName = $q->param('userName')
- }
- if(defined $q->param('password')){
- $password = $q->param('password')
- }
- if($userName && $password){
- $request->{becomeuser}->[0]->{username}->[0] = $userName;
- $request->{becomeuser}->[0]->{password}->[0] = $password;
- }
- my @data = $resources{$resource}->();
- wrapData(\@data);
-}
-
-my @groupFields = ('groupname', 'grouptype', 'members', 'wherevals', 'comments', 'disable');
-
-#resource handlers
-
-#get is done
-#post and delete are done but not tested
-#groupfiles4dsh is done but not tested
-sub groupsHandler{
- my @responses;
- my @args;
- my $groupName;
-
- #is the group name in the URI?
- if(defined $path[1]){
- $groupName = $path[1];
- }
- #in the query string?
- else{
- $groupName = $q->param('groupName');
- }
-
- if(isGet()){
- if(defined $groupName){
- $request->{command} = 'tabget';
- push @args, "groupname=$groupName";
- if(defined $q->param('field')){
- foreach ($q->param('field')){
- push @args, "nodegroup.$_";
- }
- }
- else{
- foreach (@groupFields){
- push @args, "nodegroup.$_";
- }
- }
- }
- else {
- $request->{command} = 'tabdump';
- push @args, 'nodegroup';
- }
- }
- #does it make sense to even have this?
- elsif(isPost()){
- my $nodeRange = $q->param('nodeRange');
- if(defined $groupName && defined $nodeRange){
- $request->{command} = 'mkdef';
- push @args, '-t';
- push @args, 'group';
- push @args, '-o';
- push @args, $groupName;
- push @args, "members=$nodeRange";
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "A node range and group name must be specified for creating a group");
- exit(0);
- }
- }
- elsif(isPut()){
- #handle groupfiles4dsh -p /tmp/nodegroupfiles
- if($q->param('command') eq "4dsh"){
- if($q->param('path')){
- $request->{command} = 'groupfiles4dsh';
- push @args, "p=$q->param('path')";
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The path must be specified for creating directories for dsh");
- exit(0);
- }
- }
- else{
- if(defined $groupName && defined $q->param('fields')){
- $request->{command} = 'nodegrpch';
- push @args, $groupName;
- push @args, $q->param('field');
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The group and fields must be specified to update groups");
- exit(0);
- }
- }
- }
- elsif(isDelete()){
- if(defined $groupName){
- $request->{command} = 'rmdef';
- push @args, '-d';
- push @args, 'group';
- push @args, '-o';
- push @args, $groupName;
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The group must be specified to delete a group");
- exit(0);
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
-
- return @responses;
-}
-
-my @imageFields = ('imagename','profile','imagetype','provmethod','osname','osvers','osdistro','osarch','synclists','comments','disable');
-
-#get is done, nothing else
-sub imagesHandler{
- my @responses;
- my @args;
- my $image;
-
- if(defined($path[1])){
- $image = $path[1];
- }
- else{
- $image = $q->param('imageName');
- }
-
- if(isGet()){
- if(defined $image){
- #call chkosimage, but should only be used for AIX images
- if($q->param('check')){
- $request->{command} = 'chkosimage';
- push @args, $image;
- }
- else{
- $request->{command} = 'tabget';
- push @args, "imagename=$image";
- if(defined $q->param('field')){
- foreach ($q->param('field')){
- push @args, "osimage.$_";
- }
- }
- else{
- foreach (@groupFields){
- push @args, "osimage.$_";
- }
- }
- }
- }
- #no image indicated, so list all
- else{
- $request->{command} = 'tabdump';
- push @args, 'osimage';
- }
- }
- elsif(isPost()){
-####genimage and related commands do not go through xcatd....
-####not supported at the moment
- #if($q->param('type') eq /stateless/){
- #if(!defined $image){
- #sendStatusMsg($STATUS_BAD_REQUEST, "The image name is required to create a stateless image");
- #exit(0);
- #}
- #$request->{command} = 'genimage';
- #foreach(param->{'field'}){
- #}
- #}
- #else{
- #if(defined $q->param('path')){
- #$request->{command} = 'copycds';
- #push @args, $q->param('path');
- #}
- #}
- }
- elsif(isPut() || isPatch()){
- #use chkosimage to remove any older versions of the rpms. should only be used for AIX
- if($q->param('clean')){
- if(defined $image){
- $request->{command} = 'chkosimage';
- push @args, '-c';
- push @args, $image;
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The image name is required to clean an os image");
- }
- }
- }
- elsif(isDelete()){
- if(defined $image){
- $request->{command} = 'rmimage';
- if(defined $q->param('verbose')){
- push @args, '-v';
- }
- push @args, $image;
- }
- elsif(defined $q->param('os') && defined $q->param('arch') && defined $q->param('profile')){
- push @args, '-o';
- push @args, $q->param('os');
- push @args, '-a';
- push @args, $q->param('arch');
- push @args, '-p';
- push @args, $q->param('profile');
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "Either the image name or the os, architecture and profile must be specified to remove an image");
- exit(0);
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
-
- return @responses;
-}
-
-#complete
-sub logsHandler{
- my @responses;
- my @args;
- my $logType;
-
- if(defined $path[1]){
- $logType = $path[1];
- }
- #in the query string?
- else{
- $logType = $q->param('logType');
- }
- my $nodeRange = $q->param('nodeRange');;
-
- #no real output unless the log type is defined
- if(!defined $logType){
- print $q->p("Current logs available are auditlog and eventlog");
- exit(0);
- }
-
- if(isGet()){
- if($logType eq "reventLog"){
- if(defined $nodeRange){
- $request->{command} = 'reventlog';
- push @args, $nodeRange;
- if(defined $q->param('count')){
- push @args, $q->param('count');
- }
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "nodeRange must be specified to GET remote event logs");
- }
- }
- else{
- $request->{command} = 'tabdump';
- push @args, $logType;
- }
- }
- #this clears the log
- elsif(isPut()){
- if($logType eq "reventlog"){
- if(defined $nodeRange){
- $request->{command} = 'reventlog';
- push @args, $nodeRange;
- push @args, 'clear';
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "nodeRange must be specified to GET remote event logs");
- }
- }
- else{
- $request->{command} = 'tabprune';
- #-a removes all
- push @args, '-a';
- #should it return the removed entries?
- if(defined $q->param('showRemoved'))
- {
- push @args, '-V';
- }
- }
- }
- #remove some of the entries
- elsif(isPatch()){
- $request->{command} = 'tabprune';
- #should it return the removed entries?
- if(defined $q->param('showRemoved'))
- {
- push @args, '-V';
- }
- #remove a certain number of records
- if(defined $q->param('count')){
- push @args, ('-n', $q->param('count'));
- }
- #remove a percentage of the records
- if(defined $q->param('percent')){
- push @args, ('-p', $q->param('percent'));
- }
- #remove all records before this record
- if(defined $q->param('lastRecord')){
- push @args, ('-i', $q->param('lastRecord'));
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
-
- return @responses;
-}
-
-#complete
-sub monitorsHandler{
- my @responses;
- my @args;
- my $monitor;
-
- if(defined $path[1]){
- $monitor = $path[1];
- }
- #in the query string?
- elsif(defined $q->param('monitor')){
- push @args, $q->param('monitor');
- }
- if(defined $monitor)
- {
- push @args, $monitor;
- }
-
- if(isGet()){
- $request->{command} = 'monls';
- }
- elsif(isPost()){
- $request->{command} = 'monadd';
- push @args, $q->param('name');
- if($q->param('nodeStatMon')){
- push @args, '-n';
- }
- #get the plug-in specific settings array
- for ($q->param){
- if($_ ne /name/ && $_ ne /nodeStatMon/){
- push @args, '-s';
- push @args, "$_=".$q->param($_);
- }
- }
- }
- elsif(isDelete()){
- $request->{command} = 'monrm'
- }
- elsif(isPut() || isPatch()){
- my $action = $q->param('action');
- if($action eq "start"){
- $request->{command} = 'monstart';
- }
- elsif($action eq "stop"){
- $request->{command} = 'monstop';
- }
- elsif($action eq "config"){
- $request->{command} = 'moncfg';
- }
- elsif($action eq "deconfig"){
- $request->{command} = 'mondeconfig';
- }
- else{
- unsupportedRequestType();
- }
- if(!defined $q->param('nodeRange')){
- #error
- }
- else{
- push @args, $q->param('nodeRange');
- }
- if(defined $q->param('remote')){
- push @args, '-r';
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
-
- return @responses;
-}
-
-sub networksHandler{
- my @responses;
- my @args;
-
- if(isGet()){
-
- }
- elsif(isPut() or isPatch()){
- my $subResource;
- if(defined $path[1]){
- $subResource = $path[1];
- }
-print "subResource is $subResource\n";
- if($subResource eq "hosts"){
- $request->{command} = 'makehosts';
- #is this needed?
- push @args, 'all';
- }
- elsif($subResource eq "dhcp"){
-print "got here\n";
- #allow restarting of the dhcp service. scary?
- if($q->param('command') eq "restart"){
- if(isAuthenticUser()){
- system('service dhcp restart');
- }
- else{
- exit(0);
- }
- }
- else{
- $request->{command} = 'makedhcp';
- foreach($q->param('field')){
- push @args, $_;
- }
- }
- }
- elsif($subResource eq "dns"){
- #allow restarting of the named service. scary?
- if($q->param('command') eq "restart"){
- if(isAuthenticUser()){
- system('service named restart');
- }
- }
- else{
- $request->{command} = 'makedhcp';
- foreach($q->param('field')){
- push @args, $_;
- }
- }
- }
- }
- elsif(isPost()){
-
- }
- elsif(isDelete()){
-
- }
- else{
- unsupportedRequestType();
- exit(0);
- }
-
- return @responses;
-}
-
-sub nodesHandler{
- my @responses;
- my @args;
-
- #does it specify nodes in the URI?
- if(defined $path[1]){
- $request->{noderange} = $path[1];
- }
- #in the query string?
- elsif(defined $q->param('nodeRange')){
- $request->{noderange} = $q->param('nodeRange');
- }
-
- if(isGet()){
- my $subResource;
- if(defined $path[2]){
- $subResource = $path[2];
- }
-
- if($subResource =~ "power"){
- $request->{command} = 'rpower';
- push @args, 'stat';
- }
- elsif($subResource =~ "bootState"){
- $request->{command} = 'nodeset';
- push @args,'stat';
- }
- elsif($subResource =~ "energy"){
- $request->{command} = 'renergy';
-
- #no fields will default to 'all'
- if(defined $q->param('field')){
- foreach ($q->param('field')){
- push @args, $_;
- }
- }
- }
- elsif($subResource =~ "osimage"){
-
- }
- elsif($subResource =~ "status"){
- $request->{command} = 'nodestat';
- }
- elsif($subResource =~ "inventory"){
- $request->{command} = 'rinv';
- if(defined $q->param('field')){
- push @args, $q->param('field');
- }
- else{
- push @args, 'all';
- }
- }
- elsif($subResource =~ "location"){
- $request->{command} = 'nodels';
- push @args, 'nodepos';
- }
- else{
- $request->{command} = 'nodels';
- #if the table or field is specified in the URI
- if(defined $subResource){
- push @args, $subResource;
- }
- #maybe it's specified in the parameters
- else{
- push @args, $q->param('field');
- }
- }
- }
- #PUT will remove and readd the nodes
- #is that true?
- elsif(isPut()){
- my $subResource;
- if(defined $path[2]){
- $subResource = $path[2];
- }
- if($subResource =~ "bootState"){
- $request->{command} = 'nodeset';
- if(defined $q->param('boot')){
- push @args, 'boot';
- }
- if(defined $q->param('install')){
- if($q->param('install')){
- push @args, "install=".$q->param('install');
- }
- else{
- push @args, 'install';
- }
- }
- if(defined $q->param('netboot')){
- if($q->param('netboot')){
- push @args, "netboot=".$q->param('netboot');
- }
- else{
- push @args, 'netboot';
- }
- }
- if(defined $q->param('statelite')){
- if($q->param('statelite')){
- push @args, "statelite=".$q->param('statelite');
- }
- else{
- push @args, 'statelite';
- }
- }
- if(defined $q->param('bmcsetup')){
- push @args, "runcmd=bmcsetup";
- }
- if(defined $q->param('shell')){
- push @args, 'shell';
- }
- }
- else{
- sendErrorMessage($STATUS_BAD_REQUEST, "The subResource \'$request->{subResource}\' does not exist");
- }
- }
- elsif(isPost()){
- $request->{command} = 'nodeadd';
- if(defined $q->param('groups')){
- $request->{groups} = $q->param('groups');
- }
-
- #since we can't predict which table fields will be passed
- #we just pass everything else
- for my $arg ($q->param){
- if($arg !~ "nodeRange" && $arg !~ "groups"){
- push @args, $arg;
- }
- }
- }
- elsif(isPatch()){
- $request->{command} = 'nodech';
- }
- elsif(isDelete()){
- #FYI: the nodeRange for delete has to be specified in the URI
- $request->{command} = 'noderm';
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
-
- #if($element->{node}){
- #print "
";
- #foreach my $item (@{$element->{node}}){
- #print "$item->{name}[0] | ";
- #if(exists $item->{data}[0]->{desc}[0]){
- #print "$item->{data}[0]->{desc}[0] | ";
- #}
- #if(exists $item->{data}[0]->{contents}[0]){
- #print "$item->{data}[0]->{contents}[0] | ";
- #}
- #print "
";
- #}
- #print "
";
- #}
- return @responses;
-}
-
-my @notificationFields = ('filename', 'tables', 'tableops', 'comments', 'disable');
-
-#complete, unless there is some way to alter existing notifications
-sub notificationsHandler{
- my @responses;
- my @args;
-
- #does not support using the notification fileName in the URI
-
- if(isGet()){
- if(defined $q->param('fileName')){
- $request->{command} = 'gettab';
- push @args, "filename".$q->param('fileName');
-
- #if they specified the fields, just get those
- if(defined $q->param('field')){
- foreach ($q->param('field')){
- push @args, $_;
- }
- }
- #else show all of the fields
- else{
- foreach (@notificationFields){
- push @args, "notification.$_";
- }
- }
- }
- else{
- $request->{command} = 'tabdump';
- push @args, "notification";
- }
- }
- elsif(isPost()){
- $request->{command} = 'regnotif';
- if(!defined $q->param('fileName') || !defined $q->param('table') || !defined $q->param('operation')){
- sendStatusMsg($STATUS_BAD_REQUEST, "fileName, table and operation must be specified for a POST on /notifications");
- }
- else{
- push @args, $q->param('fileName');
- my $tables;
- foreach ($q->param('table')){
- $tables .= "$_,";
- }
- #get rid of the extra comma
- chop($tables);
- push @args, $tables;
- push @args, '-o';
- my $operations;
- foreach ($q->param('operation')){
- $operations .= "$_,";
- }
- #get rid of the extra comma
- chop($operations);
- push @args, $q->param('operation');
- }
- }
- elsif(isDelete()){
- $request->{command} = 'unregnotif';
- if(defined $q->param('fileName')){
- push @args, $q->param('fileName');
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "fileName must be specified for a DELETE on /notifications");
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- print "request is ".Dumper($request);
- my $req = genRequest();
- @responses = sendRequest($req);
-
- return @responses;
-}
-
-my @policyFields = ('priority','name','host','commands','noderange','parameters','time','rule','comments','disable');
-
-#complete
-sub policiesHandler{
- my @responses;
- my @args;
- my $priority;
-
- #does it specify the prioirty in the URI?
- if(defined $path[1]){
- $priority = $path[1];
- }
- #in the query string?
- elsif(defined $q->param('priority')){
- $priority = $q->param('priority');
- }
-
- if(isGet()){
- if(defined $priority){
- $request->{command} = 'gettab';
- push @args, "priority=$priority";
- my @fields = $q->param('field');
-
- #if they specified fields to retrieve
- if(@fields){
- push @args, @fields;
- }
- #give them everything if nothing is specified
- else{
- foreach (@policyFields){
- push @args, "policy.$_";
- }
- }
- }
- else{
- $request->{command} = 'tabdump';
- push @args, 'policy';
- }
- }
- elsif(isPost()){
- if(defined $priority){
- $request->{command} = 'tabch';
- push @args, "priority=$priority";
- for ($q->param){
- if($_ ne /priority/){
- push @args, "policy.$_=".$q->param($_);
- }
- }
- }
- #some response about the priority being required
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The priority must be specified when creating a policy");
- exit(0);
- }
- }
- elsif(isDelete()){
- #just allowing a delete by priority at the moment, could expand this to anything
- if(defined $priority){
- $request->{command} = 'tabch';
- push @args, '-d';
- push @args, "priority=$priority";
- push @args, "policy";
- }
- }
- elsif(isPut() || isPatch()){
- if(defined $priority){
- $request->{command} = 'tabch';
- push @args, "priority=$priority";
- for ($q->param){
- if($_ ne /priority/){
- push @args, "policy.$_=".$q->param($_);
- }
- }
- }
- #some response about the priority being required
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The priority must be specified when updating a policy");
- exit(0);
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- print "request is ".Dumper($request);
- my $req = genRequest();
- @responses = sendRequest($req);
-
- return @responses;
-}
-
-#complete
-sub siteHandler{
- my @data;
- my @responses;
- my @args;
-
- if(isGet()){
- $request->{command} = 'tabdump';
- push @{$request->{arg}}, 'site';
- my $req = genRequest();
- @responses = sendRequest($req);
- }
- elsif(isPut() || isPatch()){
- $request->{command} = 'tabch';
- if(defined $q->param('PUTDATA')){
- my $entries = decode_json $q->param('PUTDATA');;
- foreach (values %$entries){
- my %fields = %$_;
- foreach my $key (keys %fields){
- if($key =~ /key/){
- #the key needs to be first
- unshift @args, "key=$fields{$key}";
- }
- else{
- push @args, "site.$key=$fields{$key}";
- }
- }
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- my @subResponses = sendRequest($req);
- #TODO: look at the reponses and see if there are errors
- push @responses, @subResponses;
- }
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- #change response formatting
- foreach my $response (@responses){
- foreach my $item (@{$response->{data}}){
- if($item !~ /^#/)
- {
- my @values = split(/,/, $item);
- my %item = (
- entry => $values[0],
- value => $values[1],
- comments => $values[2],
- disable => $values[3]);
- push @data, \%item;
- }
- }
- }
- return @responses;
-}
-
- my $formatType;
-
-#provide direct table access
-#complete and tested on the site table
-#use of the actual DELETE doesn't seem to fit here, since a resource would not be deleted
-#using PUT or PATCH instead, though it doesn't feel all that correct either
-sub tablesHandler{
- my @responses;
- my $table;
- my @args;
-
- #is the table name specified in the URI?
- if(defined $path[1]){
- $table = $path[1];
- }
-
- #handle all gets
- if(isGet()){
- $request->{command} = 'tabdump';
- if(defined $q->param('desc')){
- push @args, '-d';
- }
-
- #table was specified
- if (defined $table){
- push @args, $table;
- if(!defined $q->param('desc')){
- $formatType = 'splitCommas';
- }
- }
- }
- elsif(isPut() || isPatch()){
- my $condition = $q->param('condition');
- if(!defined $table || !defined $condition){
- sendStatusMsg($STATUS_BAD_REQUEST, "The table and condition must be specified when adding, changing or deleting an entry");
- exit(0);
- }
- $request->{command} = 'tabch';
- if(defined $q->param('delete')){
- push @args, '-d';
- push @args, $condition;
- push @args, $table;
- }
- else{
- push @args, $condition;
- for($q->param('value')){
- push @args, "$table.$_";
- }
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
- return @responses;
-}
-
-my @accountFields = ('key', 'username', 'password', 'cryptmethod', 'comments', 'disable');
-
-#done aside from being able to change cluster users, which xcat can't do yet
-sub accountsHandler{
- my @responses;
- my @args;
- my $key = $q->param('key');
-
- if(isGet()){
-
- #passwd table
- if(!defined $q->param('clusterUser')){
- if(defined $key){
- $request->{command} = 'tabget';
- push @args, "key=$key";
- if(defined $q->param('field')){
- foreach ($q->param('field')){
- push @args, "passwd.$_";
- }
- }
- else{
- foreach (@accountFields){
- push @args, "passwd.$_";
- }
- }
- }
- }
- #cluster user list
- else{
- $request->{command} = 'xcatclientnnr';
- push @args, 'clusteruserlist';
- push @args, '-p';
- }
- }
- elsif(isPost()){
- if(!defined $q->param('clusterUser')){
- if(defined $key){
- $request->{command} = 'tabch';
- push @args, "key=$key";
- for ($q->param){
- if($_ !~ /key/){
- push @args, "passwd.$_=".$q->param($_);
- }
- }
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The key must be specified when creating a non-cluster user");
- exit(0);
- }
- }
- #active directory user
- else{
- if(defined $q->param('userName') && defined $q->param('userPass')){
- $request->{command} = 'xcatclientnnr';
- push @args, 'clusteruseradd';
- push @args, $q->param('userName');
- push @{$request->{arg}}, @args;
- $request->{environment} = {XCAT_USERPASS => $q->param('userPass')};
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The key must be specified when creating a cluster user");
- exit(0);
- }
- }
- }
- elsif(isDelete()){
- if(!defined $q->param('clusterUser')){
- #just allowing a delete by key at the moment, could expand this to anything
- if(defined $key){
- $request->{command} = 'tabch';
- push @args, '-d';
- push @args, "key=$key";
- push @args, "passwd";
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The key must be specified when deleting a non-cluster user");
- exit(0);
- }
- }
- else{
- if(defined $q->param('userName')){
- $request->{command} = 'xcatclientnnr';
- push @args, 'clusteruserdel';
- push @args, $q->param('userName');
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The userName must be specified when deleting a cluster user");
- exit(0);
- }
- }
- }
- elsif(isPut() || isPatch()){
- if(!defined $q->param('clusterUser')){
- if(defined $key){
- $request->{command} = 'tabch';
- push @args, "key=$key";
- for ($q->param){
- if($_ !~ /key/){
- push @args, "passwd.$_=".$q->param($_);
- }
- }
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The key must be specified when updating a non-cluster user");
- exit(0);
- }
- }
- #TODO: there isn't currently a way to update cluster users
- else{
-
- }
- }
- else{
- unsupportedRequestType();
- exit(0);
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
- return @responses;
-}
-
-sub objectsHandler{
- my @responses;
- my @args;
- my @objectList = ("auditlog","boottarget","eventlog","firmware","group","monitoring","network","node","notification","osimage","policy","route","site");
- my %objects;
- foreach my $item (@objectList) { $objects{$item} = 1 }
- my $object;
- if(defined $path[1]){
- $object = $path[1];
- }
-
- if(isGet()){
- if(defined $object){
- $request->{command} = 'lsdef';
- push @args, '-t';
- push @args, $object;
- if($q->param('info')){
- push @args, '-h';
- }
- }
- else{
- #couldn't find a way to do this through xcatd, so shortcutting the request
- my %resp = (data => \@objectList);
- return (\%resp);
- }
- }
- elsif(isPut() || isDelete()){
-
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- @responses = sendRequest($req);
- return @responses;
-}
-
-#complete i think, tho chvm could handle args better
-sub vmsHandler{
- my @args;
- if(defined $q->param('nodeRange')){
- $request->{noderange} = $q->param('nodeRange');
- }
- if(defined $q->param('verbose')){
- push @args, '-V';
- }
-
- if(isGet()){
- $request->{command} = 'lsvm';
- if(defined $q->param('all')){
- push @args, '-a';
- }
- }
- elsif(isPost()){
- if(defined $q->param('clone')){
- $request->{command} = 'clonevm';
- if(defined $q->param('target')){
- push @args, '-t';
- push @args, $q->param('target');
- }
- if(defined $q->param('source')){
- push @args, '-b';
- push @args, $q->param('source');
- }
- if(defined $q->param('detached')){
- push @args, '-d';
- }
- if(defined $q->param('force')){
- push @args, '-f';
- }
- }
- else{
-#man page for mkvm needs updating for options
- $request->{command} = 'mkvm';
- if(defined $q->param('cec')){
- push @args, '-c';
- push @args, $q->param('cec');
- }
- if(defined $q->param('startId')){
- push @args, '-i';
- push @args, $q->param('startId');
- }
- if(defined $q->param('source')){
- push @args, '-l';
- push @args, $q->param('source');
- }
- if(defined $q->param('profile')){
- push @args, '-p';
- push @args, $q->param('profile');
- }
- if(defined $q->param('full')){
- push @args, '--full';
- }
- #if(defined $q->param('master')){
- #push @args, '-m';
- #push @args, $q->param('master');
- #}
- #if(defined $q->param('size')){
- #push @args, '-s';
- #push @args, $q->param('size');
- #}
- #if(defined $q->param('force')){
- #push @args, '-f';
- #}
- }
- }
- elsif(isPut() || isPatch()){
- $request->{command} = 'chvm';
- if(defined $q->param('field')){
- foreach ($q->param('field')){
- push @args, $_;
- }
- }
-
- }
- elsif(isDelete()){
- if(defined $request->{nodeRange}){
- if(defined $q->param('retain')){
- push @args, '-r';
- }
- if(defined $q->param('service')){
- push @args, '--service';
- }
- }
- else{
- sendStatusMsg($STATUS_BAD_REQUEST, "The node range must be specified when deleting vms");
- exit(0);
- }
- }
- else{
- unsupportedRequestType();
- exit();
- }
-
- push @{$request->{arg}}, @args;
- my $req = genRequest();
- my @responses = sendRequest($req);
- return @responses;
-}
-
-#for operations that take a 'long' time to finish, this will provide the interface to check their status
-sub jobsHandler{
-
-}
-
-
-#all data wrapping and writing is funneled through here
-sub wrapData{
- my @data = shift;
- if(exists $formatters{$format}){
- $formatters{$format}->(@data);
- }
-}
-
-sub wrapJson
-{
- my @data = shift;
- print header('application/json');
- my $json;
- $json->{'data'} = \@data;
- print to_json($json);
-}
-
-sub wrapJsonOld
-{
- my @data = shift;
- print header('application/json');
- my $json;
- $json->{'data'} = \@data;
- print to_json($json);
-}
-
-sub wrapHtml
-{
- my $item;
- my @response = shift;
- my $baseUri = $url.$pathInfo;
- if($baseUri !~ /\/^/)
- {
- $baseUri .= "/";
- }
- #print $q->p("dumping in wrapHtml ".Dumper(@response));
- foreach my $data (@response){
- if(@$data[0]->{error}){
- if(@$data[0]->{error}[0] =~ /Permission denied/ || @$data[0]->{error}[0] =~ /Authentication failure/){
- sendStatusMsg($STATUS_UNAUTH, @$data[0]->{error}[0]);
- }
- else{
- sendStatusMsg($STATUS_NOT_ACCEPTABLE, @$data[0]->{error}[0]);
- }
- exit(0);
- }
- else{
- if(isPost()){
- sendStatusMsg($STATUS_CREATED);
- }
- else{
- sendStatusMsg($STATUS_OK);
- }
- }
- foreach my $element (@$data){
- #if($element->{error}){
- if($element->{node}){
- print "";
- foreach $item (@{$element->{node}}){
- #my $url = $baseUri.$item->{name}[0];
- #print "$item->{name}[0] |
";
- print "$item->{name}[0] | ";
- if(exists $item->{data} && exists $item->{data}[0]){
- if(ref($item->{data}[0]) eq 'HASH'){
- if(exists $item->{data}[0]->{desc} && exists $item->{data}[0]->{desc}[0]){
- print "$item->{data}[0]->{desc}[0] | ";
- }
- if(ref($item->{data}[0]) eq 'HASH' && exists $item->{data}[0]->{contents}[0]){
- print "$item->{data}[0]->{contents}[0] | ";
- }
- }
- else{
- print "$item->{data}[0] | ";
- }
- }
- print "
";
- }
- print "
";
- }
- elsif($element->{data}){
- print "";
- foreach $item (@{$element->{data}}){
- my @values = split(/:/, $item, 2);
- #print "$key | $value |
";
- print "";
- foreach (@values){
- if($formatType =~ /splitCommas/){
- my @fields = split(/,/, $_,-1);
- foreach (@fields){
- print "$_ | ";
- }
- }
- else{
- print "$_ | ";
- }
- }
- print "
\n";
- }
- print "
";
- }
- elsif($element->{info}){
- foreach $item (@{$element->{info}}){
-
- print $item;
- }
- }
- }
- }
-}
-
-sub wrapXml
-{
- my @data = shift;
-
-}
-
-#general tests for valid requests and responses with HTTP codes here
-if(!doesResourceExist($resource)){
- sendStatusMsg($STATUS_NOT_FOUND, "Resource '$resource' does not exist");
- exit(0);
-}
-else{
- if($DEBUGGING){
- print $q->p("resource is $resource");
- }
- handleRequest();
-}
-
-#talk to the server
-use Socket;
-use IO::Socket::INET;
-use IO::Socket::SSL;
-use lib "/opt/xcat/lib/perl";
-use xCAT::Table;
-
-# The database initialization may take some time in the system boot scenario
-# wait for a while for the database initialization
-#do we really need to do this for the web service?
-sub sendRequest{
- my $request = shift;
- my $sitetab;
- my $retries = 0;
-
- if($DEBUGGING){
- my $preXml = $request;
- #$preXml =~ s/
< /g;
- #$preXml =~ s/>/>
/g;
- print $q->p("request XML
$preXml");
- }
- #while (!($sitetab=xCAT::Table->new('site')) && $retries < 200)
- #{
- #print ("Can not open basic site table for configuration, waiting the database to be initialized.\n");
- #sleep 1;
- #$retries++;
- #}
- #unless ($sitetab) {
- #xCAT::MsgUtils->message("S","ERROR: Unable to open basic site table for configuration");
- #die;
- #}
-#
- #my ($tmp) = $sitetab->getAttribs({'key'=>'xcatdport'},'value');
- #unless ($tmp) {
- #xCAT::MsgUtils->message("S","ERROR:Need xcatdport defined in site table, try chtab key=xcatdport site.value=3001");
- #die;
- #}
- my $port = 3001;#$tmp->{value};
- my $xcatHost = "localhost:$port";
-
- #temporary, will be using username and password
- my $homedir = "/root";
- my $keyfile = $homedir."/.xcat/client-cred.pem";
- my $certfile = $homedir."/.xcat/client-cred.pem";
- my $cafile = $homedir."/.xcat/ca.pem";
-
- my $client;
- if (-r $keyfile and -r $certfile and -r $cafile) {
- $client = IO::Socket::SSL->new(
- PeerAddr => $xcatHost,
- SSL_key_file => $keyfile,
- SSL_cert_file => $certfile,
- SSL_ca_file => $cafile,
- SSL_use_cert => 1,
- Timeout => 15,
- );
- } else {
- $client = IO::Socket::SSL->new(
- PeerAddr => $xcatHost,
- Timeout => 15,
- );
- }
- unless ($client) {
- if ($@ =~ /SSL Timeout/) {
- sendStatusMsg($STATUS_TIMEOUT, "Connection failure: SSL Timeout or incorrect certificates in ~/.xcat");
- exit(0);
- }
- else{
- sendStatusMsg($STATUS_SERVICE_UNAVAILABLE, "Connection failure: $@");
- exit(0);
- }
- }
-
- print $client $request;
-
- my $response;
- my $rsp;
- my @fullResponse;
- my $cleanexit=0;
- while (<$client>) {
- $response .= $_;
- if (m/<\/xcatresponse>/) {
- #replace ESC with xxxxESCxxx because XMLin cannot handle it
- $response =~ s/\e/xxxxESCxxxx/g;
-#print "responseXML is ".$response;
- $rsp = XMLin($response,SuppressEmpty=>undef,ForceArray=>1);
-
- #add ESC back
- foreach my $key (keys %$rsp) {
- if (ref($rsp->{$key}) eq 'ARRAY') {
- foreach my $text (@{$rsp->{$key}}) {
- next unless defined $text;
- $text =~ s/xxxxESCxxxx/\e/g;
- }
- }
- else {
- $rsp->{$key} =~ s/xxxxESCxxxx/\e/g;
- }
- }
-
- $response='';
- push (@fullResponse, $rsp);
- if ($rsp->{serverdone}) {
- $cleanexit=1;
- last;
- }
- }
- }
- unless ($cleanexit) {
- sendStatusMsg($STATUS_SERVICE_UNAVAILABLE, "ERROR/WARNING: communication with the xCAT server seems to have been ended prematurely");
- exit(0);
- }
-
- if($DEBUGGING){
- print $q->p("response ".Dumper(@fullResponse));
- }
- return @fullResponse;
-}
-
-sub isGet{
- return uc($requestType) eq "GET";
-}
-
-sub isPut{
- return uc($requestType) eq "PUT";
-}
-
-sub isPost{
- return uc($requestType) eq "POST";
-}
-
-sub isPatch{
- return uc($requestType) eq "PATCH";
-}
-
-sub isDelete{
- return uc($requestType) eq "DELETE";
-}
-
-#check to see if this is a valid user. userName and password are already set
-sub isAuthenticUser{
-print "here\n";
- $request->{command} = 'authcheck';
- my $req = genRequest();
- my @responses = sendRequest($req);
- if(@responses[0]->{data}[0] eq "Authenticated"){
- #user is authenticated
- return 1;
- }
- #authentication failure
- sendStatusMsg($STATUS_UNAUTH, @responses[0]->{error}[0]);
- return 0;
-}