Author: arkurth
Date: Tue Oct 18 17:30:53 2016
New Revision: 1765484

URL: http://svn.apache.org/viewvc?rev=1765484&view=rev
Log:
VCL-997
Added subroutines:
DataStructure.pm::get_reservation_info_json_string
OS.pm::get_reservation_info_json_file_path
OS.pm::create_reservation_info_json_file
OS.pm::delete_reservation_info_json_file
Windows.pm::get_reservation_info_json_file_path
utils.pm::prune_array_reference
utils.pm::prune_hash_child_references
utils.pm::prune_hash_reference

OS.pm::create_reservation_info_json_file gets called from reserved.pm::process 
only if a variable named 'enable_experimental_features' is true in the database.

This file is removed when a computer is sanitized in 
reclaim.pm::call_os_sanitize.


Modified:
    vcl/trunk/managementnode/lib/VCL/DataStructure.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS.pm
    vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
    vcl/trunk/managementnode/lib/VCL/reclaim.pm
    vcl/trunk/managementnode/lib/VCL/reserved.pm
    vcl/trunk/managementnode/lib/VCL/utils.pm

Modified: vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/DataStructure.pm Tue Oct 18 17:30:53 2016
@@ -77,6 +77,7 @@ use diagnostics;
 use English '-no_match_vars';
 
 use Object::InsideOut;
+use JSON qw(to_json);
 use List::Util qw(min max);
 use YAML;
 use Storable qw(dclone);
@@ -2236,6 +2237,63 @@ sub get_image_minram {
 }
 
 #/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_info_json_string
+
+ Parameters  : none
+ Returns     : string
+ Description : Constucts a JSON string based on the reservation data.
+
+=cut
+
+sub get_reservation_info_json_string {
+       my $self = shift;
+       
+       my $reservation_id = $self->reservation_id;
+       my $request_data = $self->request_data;
+       
+       # Clone the hash so that the original isn't altered
+       my $request_data_clone = dclone($request_data);
+       
+       my $json_data = {};
+       
+       # Remove useless keys
+       $request_data_clone = prune_hash_reference($request_data_clone, 
'.*(resource|current|adminlevel|nextimage|predictive|platform|log|schedule).*');
+       
+       $json_data->{request}                   = 
prune_hash_child_references($request_data_clone);
+       $json_data->{reservation}               = 
prune_hash_child_references($request_data_clone->{reservation}{$reservation_id});
+       $json_data->{imagerevision}     = 
prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{imagerevision});
+       $json_data->{image}                             = 
prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{image});
+       $json_data->{computer}                  = 
prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer});
+       
+       if 
(defined($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost}))
 {
+               $json_data->{vmhost}                    = 
prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost});
+               $json_data->{vmhost_computer}   = 
prune_hash_child_references($request_data_clone->{reservation}{$reservation_id}{computer}{vmhost}{computer});
+       }
+       
+       # TODO: figure out how to handle user info, what structure, etc
+       #$json_data->{users}                            = 
$request_data_clone->{reservation}{$reservation_id}{users};
+       #$json_data->{user} = $request_data_clone->{user};
+       #$json_data->{user}{username} = $json_data->{user}{unityid};
+       
+       # IMPORTANT: delete vmprofile data and anything else that may contain 
passwords
+       #delete $json_data->{computer}{vmhost}{vmprofile};
+       
+       # Convert the request data to JSON
+       my $json;
+       eval {
+               $json = to_json($json_data, { pretty => 1 });
+       };
+       if ($EVAL_ERROR) {
+               notify($ERRORS{'WARNING'}, 0, "failed to create convert request 
data to json, error: $EVAL_ERROR");
+               return;
+       }
+       
+       notify($ERRORS{'DEBUG'}, 0, "constructed JSON string based on 
reservation infor:\n$json");
+       return $json;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
 
 1;
 __END__

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS.pm Tue Oct 18 17:30:53 2016
@@ -4510,8 +4510,76 @@ sub get_cluster_info_file_path {
        return $self->{cluster_info_file_path};
 }
 
-#///////////////////////////////////////////////////////////////////////////
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_info_json_file_path
+
+ Parameters  : none
+ Returns     : string
+ Description : Returns the location where the files resides on the computer 
that
+               contains JSON formatted information about the reservation. For
+               Linux computers, the location is /etc/reservation_info.json.
+
+=cut
+
+sub get_reservation_info_json_file_path {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module::OS/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       return $self->{reservation_info_json_file_path} if 
$self->{reservation_info_json_file_path};
+       $self->{reservation_info_json_file_path} = '/etc/reservation_info.json';
+       notify($ERRORS{'DEBUG'}, 0, "determined reservation info JSON file path 
file path for " . ref($self) . " OS module: 
$self->{reservation_info_json_file_path}");
+       return $self->{reservation_info_json_file_path};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 create_reservation_info_json_file
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Creates a text file on the computer containing reservation data
+               in JSON format.
+
+=cut
 
+sub create_reservation_info_json_file {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module::OS/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $json_file_path = $self->get_reservation_info_json_file_path() || 
return;
+       my $json_string = $self->data->get_reservation_info_json_string() || 
return;
+       return $self->create_text_file($json_file_path, $json_string);
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 delete_reservation_info_json_file
+
+ Parameters  : none
+ Returns     : boolean
+ Description : Deletes the text file on the computer containing reservation 
data
+                                       in JSON format. This is important when 
sanitizing a computer.
+
+=cut
+
+sub delete_reservation_info_json_file {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module::OS/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       
+       my $json_file_path = $self->get_reservation_info_json_file_path() || 
return;
+       return $self->delete_file($json_file_path);
+}
+
+#///////////////////////////////////////////////////////////////////////////
 1;
 __END__
 

Modified: vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/Module/OS/Windows.pm Tue Oct 18 17:30:53 
2016
@@ -10973,7 +10973,7 @@ sub run_script {
                notify($ERRORS{'WARNING'}, 0, "failed to execute script on 
$computer_node_name: '$script_path', command: '$command'");
                return;
        }
-       
+
        # Create a log file containing the output
        my $logfile_contents = "$timestamp - $script_path executed by vcld";
        my $header_line_length = length($logfile_contents);
@@ -12019,6 +12019,30 @@ sub get_cluster_info_file_path {
        return $self->{cluster_info_file_path};
 }
 
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 get_reservation_info_json_file_path
+
+ Parameters  : none
+ Returns     : string
+ Description : Returns the location where the files resides on the computer 
that
+               contains JSON formatted information about the reservation.
+
+=cut
+
+sub get_reservation_info_json_file_path {
+       my $self = shift;
+       if (ref($self) !~ /VCL::Module::OS/i) {
+               notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a 
function, it must be called as a class method");
+               return;
+       }
+       return $self->{reservation_info_json_file_path} if 
$self->{reservation_info_json_file_path};
+       
+       my $systemroot_value = 
$self->get_environment_variable_value('SYSTEMDRIVE') || 'C:';
+       $self->{reservation_info_json_file_path} = 
"$systemroot_value/reservation_info.json";
+       notify($ERRORS{'DEBUG'}, 0, "determined reservation info JSON file path 
file path for " . ref($self) . " OS module: 
$self->{reservation_info_json_file_path}");
+       return $self->{reservation_info_json_file_path};
+}
 
 #/////////////////////////////////////////////////////////////////////////////
 

Modified: vcl/trunk/managementnode/lib/VCL/reclaim.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reclaim.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reclaim.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reclaim.pm Tue Oct 18 17:30:53 2016
@@ -329,6 +329,13 @@ sub call_os_sanitize {
        
        my $computer_shortname = $self->data->get_computer_short_name();
        
+       # Delete the reservation info JSON file
+       my $enable_experimental_features = 
get_variable('enable_experimental_features', 0);
+       if ($enable_experimental_features && 
!$self->os->delete_reservation_info_json_file()) {
+               notify($ERRORS{'WARNING'}, 0, "failed to delete reservation 
info JSON file on $computer_shortname, computer will be reloaded");
+               $self->insert_reload_and_exit();
+       }
+       
        # Attempt to call OS module's sanitize() subroutine
        # This subroutine should perform all the tasks necessary to sanitize 
the OS if it was reserved and not logged in to
        notify($ERRORS{'DEBUG'}, 0, "calling " . ref($self->os) . "::sanitize() 
subroutine");

Modified: vcl/trunk/managementnode/lib/VCL/reserved.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/reserved.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/reserved.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/reserved.pm Tue Oct 18 17:30:53 2016
@@ -200,6 +200,12 @@ sub process {
                $self->reservation_failed("update_cluster failed");
        }
        
+       # Create a JSON file containing the reservation info
+       my $enable_experimental_features = 
get_variable('enable_experimental_features', 0);
+       if ($enable_experimental_features) {
+               $self->os->create_reservation_info_json_file();
+       }
+       
        # Check if OS module's post_reserve() subroutine exists
        if ($self->os->can("post_reserve") && !$self->os->post_reserve()) {
                $self->reservation_failed("OS module post_reserve failed");

Modified: vcl/trunk/managementnode/lib/VCL/utils.pm
URL: 
http://svn.apache.org/viewvc/vcl/trunk/managementnode/lib/VCL/utils.pm?rev=1765484&r1=1765483&r2=1765484&view=diff
==============================================================================
--- vcl/trunk/managementnode/lib/VCL/utils.pm (original)
+++ vcl/trunk/managementnode/lib/VCL/utils.pm Tue Oct 18 17:30:53 2016
@@ -70,6 +70,7 @@ use List::Util qw(min max);
 use HTTP::Headers;
 use RPC::XML::Client;
 use Scalar::Util 'blessed';
+use Storable qw(dclone);
 use Data::Dumper;
 use Cwd;
 use Sys::Hostname;
@@ -223,6 +224,9 @@ our @EXPORT = qw(
        parent_directory_path
        populate_reservation_natport
        preplogfile
+       prune_array_reference
+       prune_hash_child_references
+       prune_hash_reference
        read_file_to_array
        remove_array_duplicates
        rename_vcld_process
@@ -2506,7 +2510,7 @@ sub known_hosts {
 =head2 getusergroupmembers
 
  Parameters  : usergroupid
- Returns     : array of user group memebers
+ Returns     : array of user group members
  Description : queries database and collects user members of supplied 
usergroupid
 
 =cut
@@ -7164,7 +7168,7 @@ sub get_computer_info {
        # Add the column for predictive module info
    my @columns = @{$database_table_columns->{module}};
    for my $column (@columns) {
-         $select_statement .= "predictivemodule.$column AS 
'predictivemodule-$column',\n";
+      $select_statement .= "predictivemodule.$column AS 
'predictivemodule-$column',\n";
    }
        
        # Remove the comma after the last column line
@@ -14377,6 +14381,159 @@ sub wrap_string {
 }
 
 #/////////////////////////////////////////////////////////////////////////////
+
+=head2 prune_hash_reference
+
+ Parameters  : $hash_ref, $prune_regex
+ Returns     : hash reference
+ Description : 
+
+=cut
+
+sub prune_hash_reference {
+       my ($hash_ref_argument, $prune_regex) = @_;
+       if (!defined($hash_ref_argument)) {
+               notify($ERRORS{'WARNING'}, 0, "hash reference argument was not 
supplied");
+               return;
+       }
+       elsif (!ref($hash_ref_argument) || ref($hash_ref_argument) ne 'HASH') {
+               notify($ERRORS{'WARNING'}, 0, "argument is not a hash 
reference:\n" . format_data($hash_ref_argument));
+               return;
+       }
+       elsif (!defined($prune_regex)) {
+               notify($ERRORS{'WARNING'}, 0, "prune regex argument was not 
supplied, returning original hash reference");
+               return $hash_ref_argument;
+       }
+       
+       # Create a clone if this wasn't recursively called
+       my $calling_subroutine = get_calling_subroutine();
+       my $hash_ref;
+       if ($calling_subroutine =~ /^prune/) {
+               $hash_ref = $hash_ref_argument;
+       }
+       else {
+               $hash_ref = dclone($hash_ref_argument);
+       }
+       
+       my $result = {};
+       for my $key (keys %$hash_ref) {
+               # Don't add keys which match the regex
+               if ($key =~ /$prune_regex/) {
+                       next;
+               }
+               
+               my $type = ref($hash_ref->{$key});
+               if (!$type) {
+                       # If the value is not a reference, simply add it to the 
result
+                       $result->{$key} = $hash_ref->{$key};
+                       next;
+               }
+               elsif ($type eq 'HASH') {
+                       $result->{$key} = 
prune_hash_reference($hash_ref->{$key}, $prune_regex);
+               }
+               elsif ($type eq 'ARRAY') {
+                       $result->{$key} = 
prune_array_reference($hash_ref->{$key}, $prune_regex);
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "unsupported type: 
$type");
+               }
+       }
+       return $result;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 prune_array_reference
+
+ Parameters  : $array_ref, $prune_regex
+ Returns     : array reference
+ Description : 
+
+=cut
+
+sub prune_array_reference {
+       my ($array_ref_argument, $prune_regex) = @_;
+       if (!defined($array_ref_argument)) {
+               notify($ERRORS{'WARNING'}, 0, "array reference argument was not 
supplied");
+               return;
+       }
+       elsif (!ref($array_ref_argument) || ref($array_ref_argument) ne 
'ARRAY') {
+               notify($ERRORS{'WARNING'}, 0, "argument is not a array 
reference:\n" . format_data($array_ref_argument));
+               return;
+       }
+       elsif (!defined($prune_regex)) {
+               notify($ERRORS{'WARNING'}, 0, "prune regex argument was not 
supplied, returning original array reference");
+               return $array_ref_argument;
+       }
+       
+       # Create a clone if this wasn't recursively called
+       my $calling_subroutine = get_calling_subroutine();
+       my $array_ref;
+       if ($calling_subroutine =~ /^prune/) {
+               $array_ref = $array_ref_argument;
+       }
+       else {
+               $array_ref = dclone($array_ref_argument);
+       }
+       
+       my $result = [];
+       for my $element (@$array_ref) {
+               my $type = ref($element);
+               if (!$type) {
+                       push @$result, $element;
+               }
+               elsif ($type eq 'ARRAY') {
+                       push @$result, prune_array_reference($element, 
$prune_regex);
+               }
+               elsif ($type eq 'HASH') {
+                       push @$result, prune_hash_reference($element, 
$prune_regex);
+               }
+               else {
+                       notify($ERRORS{'WARNING'}, 0, "unsupported type: 
$type");
+               }
+       }
+       
+       return $result;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 prune_hash_child_references
+
+ Parameters  : $hash_ref
+ Returns     : hash reference
+ Description : Makes a copy of the hash reference. Removes all keys that 
contain
+               references as data.
+
+=cut
+
+sub prune_hash_child_references {
+       my ($hash_ref_argument) = @_;
+       if (!defined($hash_ref_argument)) {
+               notify($ERRORS{'WARNING'}, 0, "hash reference argument was not 
supplied");
+               return;
+       }
+       elsif (!ref($hash_ref_argument) || ref($hash_ref_argument) ne 'HASH') {
+               notify($ERRORS{'WARNING'}, 0, "argument is not a hash 
reference:\n" . format_data($hash_ref_argument));
+               return;
+       }
+       
+       # Create a clone
+       my $hash_ref = dclone($hash_ref_argument);
+       
+       my $result = {};
+       for my $key (keys %$hash_ref) {
+               if (ref($hash_ref->{$key})) {
+                       next;
+               }
+               else {
+                       $result->{$key} = $hash_ref->{$key};
+               }
+       }
+       return $result;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
 
 1;
 __END__


Reply via email to