| #!/usr/bin/perl -w |
| ############################################################################### |
| # $Id$ |
| ############################################################################### |
| # Licensed to the Apache Software Foundation (ASF) under one or more |
| # contributor license agreements. See the NOTICE file distributed with |
| # this work for additional information regarding copyright ownership. |
| # The ASF licenses this file to You under the Apache License, Version 2.0 |
| # (the "License"); you may not use this file except in compliance with |
| # the License. You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| ############################################################################### |
| |
| =head1 NAME |
| |
| VCL::DataStructure - VCL data structure module |
| |
| =head1 SYNOPSIS |
| |
| my $data_structure; |
| eval { |
| $data_structure = new VCL::DataStructure({request_id => 66, reservation_id => 65}); |
| }; |
| if (my $e = Exception::Class::Base->caught()) { |
| die $e->message; |
| } |
| |
| # Access data by calling method on the DataStructure object |
| my $user_id = $data_structure->get_user_id; |
| |
| # Pass the DataStructure object to a module |
| my $xcat = new VCL::Module::Provisioning::xCAT({data_structure => $data_structure}); |
| |
| ... |
| |
| # Access data from xCAT.pm |
| # Note: the data() subroutine is implented by Provisioning.pm which xCAT.pm is |
| # a subclass of |
| # ->data-> could also be written as ->data()-> |
| my $management_node_id = $self->data->get_management_node_id; |
| |
| =head1 DESCRIPTION |
| |
| This module retrieves and stores data from the VCL database. It provides |
| methods to access the data. The database schema and data structures used by |
| core VCL code should not be visible to most modules. This module encapsulates |
| the data and provides an interface to access it. |
| |
| =cut |
| |
| ############################################################################### |
| package VCL::DataStructure; |
| |
| # Specify the lib path using FindBin |
| use FindBin; |
| use lib "$FindBin::Bin/.."; |
| |
| # Configure inheritance |
| use base qw(); |
| |
| # Specify the version of this module |
| our $VERSION = '2.5.1'; |
| |
| # Specify the version of Perl to use |
| use 5.008000; |
| |
| use strict; |
| use warnings; |
| 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); |
| |
| use VCL::utils; |
| |
| ############################################################################### |
| |
| =head1 CLASS ATTRIBUTES |
| |
| =cut |
| |
| =head3 %SUBROUTINE_MAPPINGS |
| |
| Data type : hash |
| Description : %SUBROUTINE_MAPPINGS hash maps subroutine names to hash keys. |
| It is used by AUTOMETHOD to return the corresponding hash data |
| when an undefined subroutine is called on a DataStructure object. |
| |
| =cut |
| |
| my %SUBROUTINE_MAPPINGS; |
| |
| # TODO: Move all keys which don't come straight from the database to the top |
| $SUBROUTINE_MAPPINGS{process_pid} = '$self->request_data->{PID}'; |
| $SUBROUTINE_MAPPINGS{process_ppid} = '$self->request_data->{PPID}'; |
| $SUBROUTINE_MAPPINGS{image_capture_type} = '$self->request_data->{IMAGE_CAPTURE_TYPE}'; |
| $SUBROUTINE_MAPPINGS{notice_interval} = '$self->request_data->{NOTICE_INTERVAL}'; |
| |
| $SUBROUTINE_MAPPINGS{blockrequest_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{id}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_name} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{name}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_image_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{imageid}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_number_machines} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{numMachines}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_group_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{groupid}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_group_name} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{groupname}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_repeating} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{repeating}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_owner_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{ownerid}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_management_node_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{managementnodeid}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_expire} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{expireTime}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_processing} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{processing}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_mode} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{MODE}'; |
| |
| $SUBROUTINE_MAPPINGS{blockrequest_blocktimes_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{BLOCKTIMES_ID}'; |
| |
| $SUBROUTINE_MAPPINGS{blockrequest_owner_email} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{owner}{email}'; |
| $SUBROUTINE_MAPPINGS{blockrequest_owner_affiliation_helpaddress} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{owner}{affiliation}{helpaddress}'; |
| |
| $SUBROUTINE_MAPPINGS{blockrequest_image_prettyname} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{image}{prettyname}'; |
| |
| $SUBROUTINE_MAPPINGS{blocktime_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{id}'; |
| #$SUBROUTINE_MAPPINGS{blocktime_blockrequest_id} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{blockRequestid}'; |
| $SUBROUTINE_MAPPINGS{blocktime_start} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{start}'; |
| $SUBROUTINE_MAPPINGS{blocktime_end} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{end}'; |
| $SUBROUTINE_MAPPINGS{blocktime_processed} = '$self->blockrequest_data->{BLOCKREQUEST_ID}{blockTimes}{BLOCKTIME_ID}{processed}'; |
| |
| $SUBROUTINE_MAPPINGS{request_check_time} = '$self->request_data->{CHECKTIME}'; |
| $SUBROUTINE_MAPPINGS{request_modified_time} = '$self->request_data->{datemodified}'; |
| $SUBROUTINE_MAPPINGS{request_requested_time} = '$self->request_data->{daterequested}'; |
| $SUBROUTINE_MAPPINGS{request_end_time} = '$self->request_data->{end}'; |
| $SUBROUTINE_MAPPINGS{request_forimaging} = '$self->request_data->{forimaging}'; |
| $SUBROUTINE_MAPPINGS{request_id} = '$self->request_data->{id}'; |
| $SUBROUTINE_MAPPINGS{request_laststate_id} = '$self->request_data->{laststateid}'; |
| $SUBROUTINE_MAPPINGS{request_log_id} = '$self->request_data->{logid}'; |
| $SUBROUTINE_MAPPINGS{request_notice_interval} = '$self->request_data->{NOTICEINTERVAL}'; |
| $SUBROUTINE_MAPPINGS{request_preload} = '$self->request_data->{preload}'; |
| $SUBROUTINE_MAPPINGS{request_preload_only} = '$self->request_data->{PRELOADONLY}'; |
| $SUBROUTINE_MAPPINGS{request_reservation_count} = '$self->request_data->{RESERVATIONCOUNT}'; |
| $SUBROUTINE_MAPPINGS{request_start_time} = '$self->request_data->{start}'; |
| $SUBROUTINE_MAPPINGS{request_duration_epoch} = '$self->request_data->{DURATION}'; |
| $SUBROUTINE_MAPPINGS{request_checkuser} = '$self->request_data->{checkuser}'; |
| #$SUBROUTINE_MAPPINGS{request_stateid} = '$self->request_data->{stateid}'; |
| $SUBROUTINE_MAPPINGS{request_test} = '$self->request_data->{test}'; |
| $SUBROUTINE_MAPPINGS{request_updated} = '$self->request_data->{UPDATED}'; |
| #$SUBROUTINE_MAPPINGS{request_userid} = '$self->request_data->{userid}'; |
| $SUBROUTINE_MAPPINGS{request_state_name} = '$self->request_data->{state}{name}'; |
| $SUBROUTINE_MAPPINGS{request_laststate_name} = '$self->request_data->{laststate}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{log_userid} = '$self->request_data->{log}{userid}'; |
| $SUBROUTINE_MAPPINGS{log_nowfuture} = '$self->request_data->{log}{nowfuture}'; |
| $SUBROUTINE_MAPPINGS{log_start} = '$self->request_data->{log}{start}'; |
| $SUBROUTINE_MAPPINGS{log_loaded} = '$self->request_data->{log}{loaded}'; |
| $SUBROUTINE_MAPPINGS{log_initialend} = '$self->request_data->{log}{initialend}'; |
| $SUBROUTINE_MAPPINGS{log_finalend} = '$self->request_data->{log}{finalend}'; |
| $SUBROUTINE_MAPPINGS{log_wasavailable} = '$self->request_data->{log}{wasavailable}'; |
| $SUBROUTINE_MAPPINGS{log_ending} = '$self->request_data->{log}{ending}'; |
| $SUBROUTINE_MAPPINGS{log_requestid} = '$self->request_data->{log}{requestid}'; |
| $SUBROUTINE_MAPPINGS{log_computerid} = '$self->request_data->{log}{computerid}'; |
| $SUBROUTINE_MAPPINGS{log_remote_ip} = '$self->request_data->{log}{remoteIP}'; |
| $SUBROUTINE_MAPPINGS{log_imageid} = '$self->request_data->{log}{imageid}'; |
| $SUBROUTINE_MAPPINGS{log_size} = '$self->request_data->{log}{size}'; |
| |
| $SUBROUTINE_MAPPINGS{sublog_id} = '$self->request_data->{reservation}{RESERVATION_ID}{SUBLOG_ID}'; |
| |
| #$SUBROUTINE_MAPPINGS{request_reservationid} = '$self->request_data->{RESERVATIONID}'; |
| $SUBROUTINE_MAPPINGS{reservation_id} = '$self->request_data->{RESERVATIONID}'; |
| |
| #$SUBROUTINE_MAPPINGS{reservation_computerid} = '$self->request_data->{reservation}{RESERVATION_ID}{computerid}'; |
| #$SUBROUTINE_MAPPINGS{reservation_id} = '$self->request_data->{reservation}{RESERVATION_ID}{id}'; |
| #$SUBROUTINE_MAPPINGS{reservation_imageid} = '$self->request_data->{reservation}{RESERVATION_ID}{imageid}'; |
| #$SUBROUTINE_MAPPINGS{reservation_imagerevisionid} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevisionid}'; |
| $SUBROUTINE_MAPPINGS{reservation_lastcheck_time} = '$self->request_data->{reservation}{RESERVATION_ID}{lastcheck}'; |
| $SUBROUTINE_MAPPINGS{reservation_machine_ready} = '$self->request_data->{reservation}{RESERVATION_ID}{MACHINEREADY}'; |
| #$SUBROUTINE_MAPPINGS{reservation_managementnodeid} = '$self->request_data->{reservation}{RESERVATION_ID}{managementnodeid}'; |
| $SUBROUTINE_MAPPINGS{reservation_password} = '$self->request_data->{reservation}{RESERVATION_ID}{pw}'; |
| #$SUBROUTINE_MAPPINGS{reservation_remote_ip} = '$self->request_data->{reservation}{RESERVATION_ID}{remoteIP}'; |
| #$SUBROUTINE_MAPPINGS{reservation_requestid} = '$self->request_data->{reservation}{RESERVATION_ID}{requestid}'; |
| $SUBROUTINE_MAPPINGS{reservation_ready} = '$self->request_data->{reservation}{RESERVATION_ID}{READY}'; |
| $SUBROUTINE_MAPPINGS{reservation_users} = '$self->request_data->{reservation}{RESERVATION_ID}{users}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_data} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}'; |
| $SUBROUTINE_MAPPINGS{computer_current_image_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimageid}'; |
| $SUBROUTINE_MAPPINGS{computer_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{deleted}'; |
| $SUBROUTINE_MAPPINGS{computer_drive_type} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{drivetype}'; |
| $SUBROUTINE_MAPPINGS{computer_dsa} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{dsa}'; |
| $SUBROUTINE_MAPPINGS{computer_dsa_pub} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{dsapub}'; |
| $SUBROUTINE_MAPPINGS{computer_eth0_mac_address} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{eth0macaddress}'; |
| $SUBROUTINE_MAPPINGS{computer_eth1_mac_address} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{eth1macaddress}'; |
| #$SUBROUTINE_MAPPINGS{computer_host} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{host}'; |
| $SUBROUTINE_MAPPINGS{computer_hostname} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{hostname}'; |
| $SUBROUTINE_MAPPINGS{computer_host_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{hostname}'; |
| #$SUBROUTINE_MAPPINGS{computer_hostpub} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{hostpub}'; |
| $SUBROUTINE_MAPPINGS{computer_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{id}'; |
| $SUBROUTINE_MAPPINGS{computer_imagerevision_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{imagerevisionid}'; |
| $SUBROUTINE_MAPPINGS{computer_lastcheck_time} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{lastcheck}'; |
| $SUBROUTINE_MAPPINGS{computer_location} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{location}'; |
| $SUBROUTINE_MAPPINGS{computer_networking_speed} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{network}'; |
| $SUBROUTINE_MAPPINGS{computer_node_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{NODENAME}'; |
| $SUBROUTINE_MAPPINGS{computer_notes} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{notes}'; |
| $SUBROUTINE_MAPPINGS{computer_owner_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{ownerid}'; |
| $SUBROUTINE_MAPPINGS{computer_platform_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{platformid}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimageid}'; |
| $SUBROUTINE_MAPPINGS{computer_private_ip_address} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{privateIPaddress}'; |
| $SUBROUTINE_MAPPINGS{computer_public_ip_address} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{IPaddress}'; |
| $SUBROUTINE_MAPPINGS{computer_processor_count} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{procnumber}'; |
| $SUBROUTINE_MAPPINGS{computer_processor_speed} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{procspeed}'; |
| $SUBROUTINE_MAPPINGS{computer_ram} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{RAM}'; |
| $SUBROUTINE_MAPPINGS{computer_rsa} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{rsa}'; |
| $SUBROUTINE_MAPPINGS{computer_rsa_pub} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{rsapub}'; |
| $SUBROUTINE_MAPPINGS{computer_schedule_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{scheduleid}'; |
| $SUBROUTINE_MAPPINGS{computer_short_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{SHORTNAME}'; |
| $SUBROUTINE_MAPPINGS{computer_state_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{stateid}'; |
| $SUBROUTINE_MAPPINGS{computer_state_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{state}{name}'; |
| $SUBROUTINE_MAPPINGS{computer_type} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{type}'; |
| $SUBROUTINE_MAPPINGS{computer_provisioning_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioningid}'; |
| $SUBROUTINE_MAPPINGS{computer_vmhost_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhostid}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_provisioning_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{name}'; |
| $SUBROUTINE_MAPPINGS{computer_provisioning_pretty_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{computer_provisioning_module_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{moduleid}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_provisioning_module_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{module}{name}'; |
| $SUBROUTINE_MAPPINGS{computer_provisioning_module_pretty_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{module}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{computer_provisioning_module_description} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{module}{description}'; |
| $SUBROUTINE_MAPPINGS{computer_provisioning_module_perl_package} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{provisioning}{module}{perlpackage}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_predictive_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictiveid}'; |
| $SUBROUTINE_MAPPINGS{computer_predictive_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{name}'; |
| $SUBROUTINE_MAPPINGS{computer_predictive_pretty_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{computer_predictive_module_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{id}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_predictive_module_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{name}'; |
| $SUBROUTINE_MAPPINGS{computer_predictive_module_pretty_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{computer_predictive_module_description} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{description}'; |
| $SUBROUTINE_MAPPINGS{computer_predictive_module_perl_package} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{predictive}{module}{perlpackage}'; |
| |
| $SUBROUTINE_MAPPINGS{nathost_info} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}'; |
| $SUBROUTINE_MAPPINGS{nathost_hostname} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{HOSTNAME}'; |
| $SUBROUTINE_MAPPINGS{nathost_date_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{datedeleted}'; |
| $SUBROUTINE_MAPPINGS{nathost_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{deleted}'; |
| $SUBROUTINE_MAPPINGS{nathost_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{id}'; |
| $SUBROUTINE_MAPPINGS{nathost_public_ip_address} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{publicIPaddress}'; |
| $SUBROUTINE_MAPPINGS{nathost_internal_ip_address} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{internalIPaddress}'; |
| $SUBROUTINE_MAPPINGS{nathost_resource_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{resource}{id}'; |
| $SUBROUTINE_MAPPINGS{nathost_resource_subid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{resource}{subid}'; |
| $SUBROUTINE_MAPPINGS{nathost_resourcetype_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{resource}{resourcetype}{id}'; |
| $SUBROUTINE_MAPPINGS{nathost_resource_type} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nathost}{resource}{resourcetype}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{vmhost_computer_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computerid}'; |
| $SUBROUTINE_MAPPINGS{vmhost_hostname} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{hostname}'; |
| $SUBROUTINE_MAPPINGS{vmhost_short_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{SHORTNAME}'; |
| $SUBROUTINE_MAPPINGS{vmhost_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{id}'; |
| $SUBROUTINE_MAPPINGS{vmhost_image_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{imageid}'; |
| $SUBROUTINE_MAPPINGS{vmhost_image_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{image}{name}'; |
| $SUBROUTINE_MAPPINGS{vmhost_ram} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{RAM}'; |
| $SUBROUTINE_MAPPINGS{vmhost_state} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{state}{name}'; |
| #$SUBROUTINE_MAPPINGS{vmhost_type} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{computer}{type}'; |
| $SUBROUTINE_MAPPINGS{vmhost_kernal_nic} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmkernalnic}'; |
| $SUBROUTINE_MAPPINGS{vmhost_vm_limit} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmlimit}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofileid}'; |
| |
| $SUBROUTINE_MAPPINGS{vmhost_profile_repository_path} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{repositorypath}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_repository_imagetype_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{repositoryimagetypeid}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_datastore_path} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{datastorepath}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_repository_imagetype_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{datastoreimagetypeid}'; |
| #$SUBROUTINE_MAPPINGS{vmhost_profile_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{id}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_image_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{imageid}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_resource_path} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{resourcepath}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_folder_path} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{folderpath}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{profilename}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_virtualswitch0} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{virtualswitch0}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_virtualswitch1} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{virtualswitch1}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_virtualswitch2} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{virtualswitch2}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_virtualswitch3} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{virtualswitch3}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_vmdisk} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{vmdisk}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_vmpath} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{vmpath}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_username} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{username}'; |
| #$SUBROUTINE_MAPPINGS{vmhost_profile_password} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{password}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_eth0generated} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{eth0generated}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_eth1generated} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{eth1generated}'; |
| $SUBROUTINE_MAPPINGS{vmhost_profile_secret_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{vmprofile}{secretid}'; |
| |
| $SUBROUTINE_MAPPINGS{vmhost_repository_imagetype_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{repositoryimagetype}{name}'; |
| $SUBROUTINE_MAPPINGS{vmhost_datastore_imagetype_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{vmhost}{datastoreimagetype}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_currentimage_data} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_data} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_architecture} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{architecture}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{deleted}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_forcheckout} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{forcheckout}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{id}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_imagemetaid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{imagemetaid}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_lastupdate} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{lastupdate}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_maxconcurrent} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{maxconcurrent}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_maxinitialtime} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{maxinitialtime}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_minnetwork} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{minnetwork}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_minprocnumber} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{minprocnumber}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_minprocspeed} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{minprocspeed}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_minram} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{minram}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{imagename}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_osid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{OSid}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_ownerid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{ownerid}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_platformid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{platformid}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_prettyname} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_project} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{project}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_reloadtime} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{reloadtime}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_size} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{size}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimage_test} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimage}{test}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_comments} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{comments}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_datecreated} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{datecreated}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{deleted}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{id}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_imageid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{imageid}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_imagename} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{imagename}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_production} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{production}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_revision} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{revision}'; |
| $SUBROUTINE_MAPPINGS{computer_currentimagerevision_userid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{currentimagerevision}{userid}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_platform_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{platform}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_nextimage_architecture} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{architecture}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{deleted}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_forcheckout} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{forcheckout}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{id}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_imagemetaid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{imagemetaid}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_lastupdate} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{lastupdate}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_maxconcurrent} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{maxconcurrent}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_maxinitialtime} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{maxinitialtime}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_minnetwork} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{minnetwork}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_minprocnumber} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{minprocnumber}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_minprocspeed} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{minprocspeed}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_minram} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{minram}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{imagename}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_osid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{OSid}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_ownerid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{ownerid}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_platformid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{platformid}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_prettyname} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_project} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{project}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_reloadtime} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{reloadtime}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_size} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{size}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimage_test} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimage}{test}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_comments} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{comments}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_datecreated} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{datecreated}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{deleted}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_id} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{id}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_imageid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{imageid}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_imagename} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{imagename}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_production} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{production}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_revision} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{revision}'; |
| $SUBROUTINE_MAPPINGS{computer_nextimagerevision_userid} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{nextimagerevision}{userid}'; |
| |
| $SUBROUTINE_MAPPINGS{computer_schedule_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{schedule}{name}'; |
| $SUBROUTINE_MAPPINGS{computer_state_name} = '$self->request_data->{reservation}{RESERVATION_ID}{computer}{state}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{image_architecture} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{architecture}'; |
| $SUBROUTINE_MAPPINGS{image_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{deleted}'; |
| $SUBROUTINE_MAPPINGS{image_forcheckout} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{forcheckout}'; |
| $SUBROUTINE_MAPPINGS{image_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{id}'; |
| $SUBROUTINE_MAPPINGS{image_identity} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{IDENTITY}'; |
| $SUBROUTINE_MAPPINGS{image_imagemetaid} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemetaid}'; |
| $SUBROUTINE_MAPPINGS{image_lastupdate} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{lastupdate}'; |
| $SUBROUTINE_MAPPINGS{image_maxconcurrent} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{maxconcurrent}'; |
| $SUBROUTINE_MAPPINGS{image_maxinitialtime} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{maxinitialtime}'; |
| $SUBROUTINE_MAPPINGS{image_minnetwork} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{minnetwork}'; |
| $SUBROUTINE_MAPPINGS{image_minprocnumber} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{minprocnumber}'; |
| $SUBROUTINE_MAPPINGS{image_minprocspeed} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{minprocspeed}'; |
| #$SUBROUTINE_MAPPINGS{image_minram} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{minram}'; |
| #$SUBROUTINE_MAPPINGS{image_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{name}'; |
| #$SUBROUTINE_MAPPINGS{image_osid} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OSid}'; |
| $SUBROUTINE_MAPPINGS{image_os_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OSid}'; |
| $SUBROUTINE_MAPPINGS{image_ownerid} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{ownerid}'; |
| $SUBROUTINE_MAPPINGS{image_platformid} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{platformid}'; |
| $SUBROUTINE_MAPPINGS{image_prettyname} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{image_project} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{project}'; |
| $SUBROUTINE_MAPPINGS{image_reload_time} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{reloadtime}'; |
| $SUBROUTINE_MAPPINGS{image_settestflag} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{SETTESTFLAG}'; |
| $SUBROUTINE_MAPPINGS{image_size} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{size}'; |
| $SUBROUTINE_MAPPINGS{image_test} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{test}'; |
| $SUBROUTINE_MAPPINGS{image_updateimagename} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{UPDATEIMAGENAME}'; |
| |
| $SUBROUTINE_MAPPINGS{imagemeta_checkuser} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{checkuser}'; |
| $SUBROUTINE_MAPPINGS{imagemeta_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{id}'; |
| $SUBROUTINE_MAPPINGS{imagemeta_postoption} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{postoption}'; |
| $SUBROUTINE_MAPPINGS{imagemeta_subimages} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{subimages}'; |
| $SUBROUTINE_MAPPINGS{imagemeta_sysprep} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{sysprep}'; |
| $SUBROUTINE_MAPPINGS{imagemeta_rootaccess} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{rootaccess}'; |
| $SUBROUTINE_MAPPINGS{imagemeta_sethostname} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagemeta}{sethostname}'; |
| |
| #$SUBROUTINE_MAPPINGS{image_domain_dns_servers} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{dnsServers}'; # Explicit subroutine |
| $SUBROUTINE_MAPPINGS{image_domain_dns_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{domainDNSName}'; |
| $SUBROUTINE_MAPPINGS{image_domain_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{id}'; |
| $SUBROUTINE_MAPPINGS{image_domain_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{name}'; |
| $SUBROUTINE_MAPPINGS{image_domain_owner_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{ownerid}'; |
| #$SUBROUTINE_MAPPINGS{image_domain_password} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{password}'; # Explicit subroutine |
| $SUBROUTINE_MAPPINGS{image_domain_secret_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{secretid}'; |
| $SUBROUTINE_MAPPINGS{image_domain_username} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{username}'; |
| $SUBROUTINE_MAPPINGS{image_domain_usedbhostnames} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{usedbhostnames}'; |
| $SUBROUTINE_MAPPINGS{image_domain_base_ou} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{imageaddomain}{baseOU}'; |
| $SUBROUTINE_MAPPINGS{image_domain_cryptsecret} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagedomain}{cryptsecret}{cryptsecret}'; |
| |
| $SUBROUTINE_MAPPINGS{image_os_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{name}'; |
| $SUBROUTINE_MAPPINGS{image_os_prettyname} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{image_os_type} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{type}'; |
| $SUBROUTINE_MAPPINGS{image_os_install_type} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{installtype}'; |
| $SUBROUTINE_MAPPINGS{image_os_minram} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{minram}'; |
| $SUBROUTINE_MAPPINGS{image_os_source_path} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{sourcepath}'; |
| $SUBROUTINE_MAPPINGS{image_os_moduleid} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{moduleid}'; |
| |
| $SUBROUTINE_MAPPINGS{image_os_module_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{module}{name}'; |
| $SUBROUTINE_MAPPINGS{image_os_module_pretty_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{module}{prettyname}'; |
| $SUBROUTINE_MAPPINGS{image_os_module_description} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{module}{description}'; |
| $SUBROUTINE_MAPPINGS{image_os_module_perl_package} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{module}{perlpackage}'; |
| |
| $SUBROUTINE_MAPPINGS{image_os_type_id} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{OStype}{id}'; |
| $SUBROUTINE_MAPPINGS{image_os_type_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{OS}{OStype}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{image_platform_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{platform}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{imagetype_name} = '$self->request_data->{reservation}{RESERVATION_ID}{image}{imagetype}{name}'; |
| |
| $SUBROUTINE_MAPPINGS{server_request_id} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{id}'; |
| $SUBROUTINE_MAPPINGS{server_request_fixed_ip} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{fixedIP}'; |
| $SUBROUTINE_MAPPINGS{server_request_router} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{router}'; |
| $SUBROUTINE_MAPPINGS{server_request_netmask} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{netmask}'; |
| $SUBROUTINE_MAPPINGS{server_request_dns_servers} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{DNSservers}'; |
| $SUBROUTINE_MAPPINGS{server_request_fixed_mac} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{fixedMAC}'; |
| $SUBROUTINE_MAPPINGS{server_request_admingroupid} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{admingroupid}'; |
| $SUBROUTINE_MAPPINGS{server_request_logingroupid} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{logingroupid}'; |
| $SUBROUTINE_MAPPINGS{server_request_monitored} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{monitored}'; |
| $SUBROUTINE_MAPPINGS{server_allow_users} = '$self->request_data->{reservation}{RESERVATION_ID}{serverrequest}{ALLOW_USERS}'; |
| |
| $SUBROUTINE_MAPPINGS{imagerevision_comments} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{comments}'; |
| $SUBROUTINE_MAPPINGS{imagerevision_date_created} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{datecreated}'; |
| $SUBROUTINE_MAPPINGS{imagerevision_deleted} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{deleted}'; |
| $SUBROUTINE_MAPPINGS{imagerevision_id} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{id}'; |
| $SUBROUTINE_MAPPINGS{imagerevision_imageid} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{imageid}'; |
| #$SUBROUTINE_MAPPINGS{imagerevision_imagename} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{imagename}'; |
| $SUBROUTINE_MAPPINGS{image_name} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{imagename}'; |
| $SUBROUTINE_MAPPINGS{imagerevision_production} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{production}'; |
| $SUBROUTINE_MAPPINGS{imagerevision_revision} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{revision}'; |
| $SUBROUTINE_MAPPINGS{imagerevision_userid} = '$self->request_data->{reservation}{RESERVATION_ID}{imagerevision}{userid}'; |
| |
| $SUBROUTINE_MAPPINGS{connect_methods} = '$self->request_data->{reservation}{RESERVATION_ID}{connect_methods}'; |
| |
| $SUBROUTINE_MAPPINGS{user_adminlevelid} = '$self->request_data->{user}{adminlevelid}'; |
| $SUBROUTINE_MAPPINGS{user_affiliationid} = '$self->request_data->{user}{affiliationid}'; |
| $SUBROUTINE_MAPPINGS{user_audiomode} = '$self->request_data->{user}{audiomode}'; |
| $SUBROUTINE_MAPPINGS{user_bpp} = '$self->request_data->{user}{bpp}'; |
| $SUBROUTINE_MAPPINGS{user_email} = '$self->request_data->{user}{email}'; |
| $SUBROUTINE_MAPPINGS{user_emailnotices} = '$self->request_data->{user}{emailnotices}'; |
| $SUBROUTINE_MAPPINGS{user_firstname} = '$self->request_data->{user}{firstname}'; |
| $SUBROUTINE_MAPPINGS{user_height} = '$self->request_data->{user}{height}'; |
| $SUBROUTINE_MAPPINGS{user_id} = '$self->request_data->{user}{id}'; |
| $SUBROUTINE_MAPPINGS{user_im_id} = '$self->request_data->{user}{IMid}'; |
| $SUBROUTINE_MAPPINGS{user_imtypeid} = '$self->request_data->{user}{IMtypeid}'; |
| $SUBROUTINE_MAPPINGS{user_lastname} = '$self->request_data->{user}{lastname}'; |
| $SUBROUTINE_MAPPINGS{user_lastupdated} = '$self->request_data->{user}{lastupdated}'; |
| $SUBROUTINE_MAPPINGS{user_mapdrives} = '$self->request_data->{user}{mapdrives}'; |
| $SUBROUTINE_MAPPINGS{user_mapprinters} = '$self->request_data->{user}{mapprinters}'; |
| $SUBROUTINE_MAPPINGS{user_mapserial} = '$self->request_data->{user}{mapserial}'; |
| $SUBROUTINE_MAPPINGS{user_preferred_name} = '$self->request_data->{user}{preferredname}'; |
| $SUBROUTINE_MAPPINGS{user_showallgroups} = '$self->request_data->{user}{showallgroups}'; |
| $SUBROUTINE_MAPPINGS{user_uid} = '$self->request_data->{user}{uid}'; |
| #$SUBROUTINE_MAPPINGS{user_unityid} = '$self->request_data->{user}{unityid}'; |
| $SUBROUTINE_MAPPINGS{user_login_id} = '$self->request_data->{user}{unityid}'; |
| $SUBROUTINE_MAPPINGS{user_width} = '$self->request_data->{user}{width}'; |
| $SUBROUTINE_MAPPINGS{user_adminlevel_name} = '$self->request_data->{user}{adminlevel}{name}'; |
| $SUBROUTINE_MAPPINGS{user_affiliation_dataupdatetext} = '$self->request_data->{user}{affiliation}{dataUpdateText}'; |
| #$SUBROUTINE_MAPPINGS{user_affiliation_helpaddress} = '$self->request_data->{user}{affiliation}{helpaddress}'; |
| $SUBROUTINE_MAPPINGS{user_affiliation_name} = '$self->request_data->{user}{affiliation}{name}'; |
| #$SUBROUTINE_MAPPINGS{user_affiliation_sitewwwaddress} = '$self->request_data->{user}{affiliation}{sitewwwaddress}'; |
| $SUBROUTINE_MAPPINGS{user_imtype_name} = '$self->request_data->{user}{IMtype}{name}'; |
| $SUBROUTINE_MAPPINGS{user_use_public_keys} = '$self->request_data->{user}{usepublickeys}'; |
| $SUBROUTINE_MAPPINGS{user_ssh_public_keys} = '$self->request_data->{user}{sshpublickeys}'; |
| |
| $SUBROUTINE_MAPPINGS{management_node_id} = '$ENV->{management_node_info}->{id}'; |
| $SUBROUTINE_MAPPINGS{management_node_ipaddress} = '$ENV->{management_node_info}->{IPaddress}'; |
| $SUBROUTINE_MAPPINGS{management_node_hostname} = '$ENV->{management_node_info}->{hostname}'; |
| $SUBROUTINE_MAPPINGS{management_node_ownerid} = '$ENV->{management_node_info}->{ownerid}'; |
| $SUBROUTINE_MAPPINGS{management_node_stateid} = '$ENV->{management_node_info}->{stateid}'; |
| $SUBROUTINE_MAPPINGS{management_node_lastcheckin} = '$ENV->{management_node_info}->{lastcheckin}'; |
| $SUBROUTINE_MAPPINGS{management_node_checkininterval} = '$ENV->{management_node_info}->{checkininterval}'; |
| $SUBROUTINE_MAPPINGS{management_node_install_path} = '$ENV->{management_node_info}->{installpath}'; |
| $SUBROUTINE_MAPPINGS{management_node_image_lib_enable} = '$ENV->{management_node_info}->{imagelibenable}'; |
| $SUBROUTINE_MAPPINGS{management_node_image_lib_group_id} = '$ENV->{management_node_info}->{imagelibgroupid}'; |
| $SUBROUTINE_MAPPINGS{management_node_image_lib_user} = '$ENV->{management_node_info}->{imagelibuser}'; |
| $SUBROUTINE_MAPPINGS{management_node_image_lib_key} = '$ENV->{management_node_info}->{imagelibkey}'; |
| $SUBROUTINE_MAPPINGS{management_node_keys} = '$ENV->{management_node_info}->{keys}'; |
| $SUBROUTINE_MAPPINGS{management_node_image_lib_partners} = '$ENV->{management_node_info}->{IMAGELIBPARTNERS}'; |
| $SUBROUTINE_MAPPINGS{management_node_short_name} = '$ENV->{management_node_info}->{SHORTNAME}'; |
| $SUBROUTINE_MAPPINGS{management_node_state_name} = '$ENV->{management_node_info}->{state}->{name}'; |
| $SUBROUTINE_MAPPINGS{management_node_os_name} = '$ENV->{management_node_info}->{OSNAME}'; |
| $SUBROUTINE_MAPPINGS{management_node_predictive_module_id} = '$ENV->{management_node_info}->{predictivemoduleid}'; |
| $SUBROUTINE_MAPPINGS{management_node_ssh_port} = '$ENV->{management_node_info}->{sshport}'; |
| |
| $SUBROUTINE_MAPPINGS{management_node_public_ip_configuration} = '$ENV->{management_node_info}->{PUBLIC_IP_CONFIGURATION}'; |
| $SUBROUTINE_MAPPINGS{management_node_public_subnet_mask} = '$ENV->{management_node_info}->{PUBLIC_SUBNET_MASK}'; |
| #$SUBROUTINE_MAPPINGS{management_node_public_default_gateway} = '$ENV{management_node_info}{PUBLIC_DEFAULT_GATEWAY}'; |
| $SUBROUTINE_MAPPINGS{management_node_public_dns_server} = '$ENV->{management_node_info}->{PUBLIC_DNS_SERVER}'; |
| |
| $SUBROUTINE_MAPPINGS{management_node_sysadmin_email} = '$ENV->{management_node_info}->{SYSADMIN_EMAIL}'; |
| $SUBROUTINE_MAPPINGS{management_node_shared_email_box} = '$ENV->{management_node_info}->{SHARED_EMAIL_BOX}'; |
| |
| $SUBROUTINE_MAPPINGS{management_node_predictive_module_name} = '$ENV->{management_node_info}->{predictive_name}'; |
| $SUBROUTINE_MAPPINGS{management_node_predictive_module_pretty_name} = '$ENV->{management_node_info}->{predictive_prettyname}'; |
| $SUBROUTINE_MAPPINGS{management_node_predictive_module_description} = '$ENV->{management_node_info}->{predictive_description}'; |
| $SUBROUTINE_MAPPINGS{management_node_predictive_module_perl_package} = '$ENV->{management_node_info}->{predictive_perlpackage}'; |
| |
| $SUBROUTINE_MAPPINGS{subroutine_mappings} = '\%SUBROUTINE_MAPPINGS'; |
| |
| ############################################################################### |
| |
| =head1 OBJECT ATTRIBUTES |
| |
| =cut |
| |
| =head3 @request_id |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @request_id : Field : Arg('Name' => 'request_id', 'Default' => 0) : Type(scalar) : Get('Name' => 'request_id', 'Private' => 1); |
| |
| =head3 @reservation_id |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @reservation_id : Field : Arg('Name' => 'reservation_id', 'Default' => 0) : Type(scalar) : Get('Name' => 'reservation_id', 'Private' => 1); |
| |
| =head3 @blockrequest_id |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @blockrequest_id : Field : Arg('Name' => 'blockrequest_id') : Type(scalar) : Get('Name' => 'blockrequest_id', 'Private' => 1); |
| |
| =head3 @blocktime_id |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @blocktime_id : Field : Arg('Name' => 'blocktime_id') : Type(scalar) : Get('Name' => 'blocktime_id', 'Private' => 1); |
| |
| |
| =head3 @request_data |
| |
| Data type : array of hashes |
| Description : |
| |
| =cut |
| |
| my @request_data : Field : Deep : Arg('Name' => 'request_data', 'Default' => {}) : Get('Name' => 'request_data', 'Private' => 1) : Set('Name' => 'refresh_request_data', 'Private' => 1); |
| |
| =head3 @blockrequest_data |
| |
| Data type : array of hashes |
| Description : |
| |
| =cut |
| |
| my @blockrequest_data : Field : Arg('Name' => 'blockrequest_data', 'Default' => {}) : Get('Name' => 'blockrequest_data', 'Private' => 1); |
| |
| =head3 @computer_identifier |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @computer_identifier : Field : Arg('Name' => 'computer_identifier') : Type(scalar) : Get('Name' => 'computer_identifier', 'Private' => 1); |
| |
| =head3 @vmhost_identifier |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @vmhost_identifier : Field : Arg('Name' => 'vmhost_identifier') : Type(scalar) : Get('Name' => 'vmhost_identifier', 'Private' => 1); |
| |
| =head3 @image_identifier |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @image_identifier : Field : Arg('Name' => 'image_identifier') : Type(scalar) : Get('Name' => 'image_identifier', 'Private' => 1); |
| |
| =head3 @image_identifier |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @imagerevision_identifier : Field : Arg('Name' => 'imagerevision_identifier') : Type(scalar) : Get('Name' => 'imagerevision_identifier', 'Private' => 1); |
| |
| =head3 @mn_os |
| |
| Data type : array of scalars |
| Description : |
| |
| =cut |
| |
| my @mn_os : Field : Arg('Name' => 'mn_os') : Get('Name' => 'mn_os', 'Private' => 1) : Set('Name' => 'set_mn_os'); |
| |
| |
| ############################################################################### |
| |
| =head1 PRIVATE OBJECT METHODS |
| |
| =cut |
| |
| =head2 initialize |
| |
| Parameters : none |
| Returns : 1 if successful, 0 if failed |
| Description : This subroutine initializes the DataStructure object. It |
| retrieves the data for the specified request ID from the |
| database and adds the data to the object. |
| |
| =cut |
| |
| sub _initialize : Init { |
| my ($self, $args) = @_; |
| |
| # Get the management node info and add it to %ENV |
| my $management_node_info = get_management_node_info(); |
| if (!$management_node_info) { |
| notify($ERRORS{'WARNING'}, 0, "unable to obtain management node info for this node"); |
| return; |
| } |
| |
| # Replace the request data with a deep copy if itself |
| # This creates entirely separate copies in case multiple DataStructure objects are used |
| # If not deep copied, the separate objects will alter each other's data |
| $self->refresh_request_data(dclone($self->request_data)) if $self->request_data; |
| |
| # Set the request and reservation IDs in the request data hash if they are undefined |
| $self->request_data->{id} = ($self->request_id || 0) if (!defined($self->request_data->{id})); |
| $self->request_data->{RESERVATIONID} = ($self->reservation_id || 0) if (!defined($self->request_data->{RESERVATIONID})); |
| if ($self->request_data->{RESERVATIONID} == 0) { |
| $self->request_data->{reservation}{0}{serverrequest}{id} = 0; |
| $self->request_data->{forimaging} = 0; |
| $self->request_data->{state}{name} = "available"; |
| |
| } |
| |
| my $computer_identifier = $self->computer_identifier; |
| my $vmhost_identifier = $self->vmhost_identifier; |
| my $image_identifier = $self->image_identifier; |
| my $imagerevision_identifier = $self->imagerevision_identifier; |
| |
| # Get the computer info if the computer_identifier argument was specified and add it to this object |
| if ($computer_identifier) { |
| notify($ERRORS{'DEBUG'}, 0, "computer identifier argument was specified, retrieving data for computer: $computer_identifier"); |
| my $computer_info = get_computer_info($computer_identifier, 1); |
| if (!$computer_info) { |
| notify($ERRORS{'WARNING'}, 0, "DataStructure object could not be initialized, failed to retrieve data for computer: $computer_identifier"); |
| |
| # Throw an exception because simply returning undefined (return;) does not result in this DataStructure object being undefined |
| Exception::Class::Base->throw(error => "DataStructure object could not be initialized, failed to retrieve data for computer: $computer_identifier"); |
| return; |
| } |
| |
| $self->request_data->{reservation}{$self->reservation_id}{computer} = $computer_info; |
| } |
| |
| # Get the VM host info if the $vmhost_identifier argument was specified and add it to this object |
| if ($vmhost_identifier) { |
| notify($ERRORS{'DEBUG'}, 0, "VM host identifier argument was specified, retrieving data for VM host: $vmhost_identifier"); |
| my $vmhost_info = get_vmhost_info($vmhost_identifier, 1); |
| if (!$vmhost_info) { |
| notify($ERRORS{'WARNING'}, 0, "DataStructure object could not be initialized, failed to retrieve data for VM host: $vmhost_identifier"); |
| |
| # Throw an exception because simply returning undefined (return;) does not result in this DataStructure object being undefined |
| Exception::Class::Base->throw(error => "DataStructure object could not be initialized, failed to retrieve data for VM host: $vmhost_identifier"); |
| return; |
| } |
| $self->request_data->{reservation}{$self->reservation_id}{computer}{vmhost} = $vmhost_info; |
| } |
| |
| # If either the computer, image, or imagerevision identifier arguments are specified, retrieve appropriate image and imagerevision data |
| if (defined($imagerevision_identifier) || defined($image_identifier) || defined($computer_identifier)) { |
| my $imagerevision_info; |
| |
| if (defined($imagerevision_identifier)) { |
| $imagerevision_identifier = 'noimage' if !$imagerevision_identifier; |
| notify($ERRORS{'DEBUG'}, 0, "imagerevision identifier argument was specified: $imagerevision_identifier, DataStructure object will contain image information for this imagerevision: $imagerevision_identifier"); |
| $imagerevision_info = get_imagerevision_info($imagerevision_identifier); |
| } |
| elsif (defined($image_identifier)) { |
| $image_identifier = 'noimage' if !$image_identifier; |
| notify($ERRORS{'DEBUG'}, 0, "image identifier argument was specified: $image_identifier, DataStructure object will contain image information for the production imagerevision of this image"); |
| $imagerevision_info = get_production_imagerevision_info($image_identifier); |
| } |
| elsif (defined($computer_identifier)) { |
| my $imagerevision_id = $self->get_computer_imagerevision_id(); |
| if (defined($imagerevision_id)) { |
| notify($ERRORS{'DEBUG'}, 0, "computer identifier argument was specified ($computer_identifier) but image and imagerevision ID arguments were not, DataStructure object will contain image information for the computer's current imagerevision ID: $imagerevision_id"); |
| if (!$imagerevision_id) { |
| notify($ERRORS{'DEBUG'}, 0, "computer identifier argument was specified ($computer_identifier) imagerevision_id is set to $imagerevision_id"); |
| my $image_id = $self->get_computer_currentimage_id(); |
| if (defined($image_id)) { |
| $imagerevision_info = get_production_imagerevision_info($image_id); |
| } |
| else { |
| Exception::Class::Base->throw(error => "DataStructure object could not be initialized, computer's current imagerevision ID could not be retrieved from the current DataStructure data:\n" . format_data($self->get_request_data)); |
| return; |
| } |
| } |
| else { |
| $imagerevision_info = get_imagerevision_info($imagerevision_id); |
| } |
| } |
| else { |
| Exception::Class::Base->throw(error => "DataStructure object could not be initialized, computer's current imagerevision ID could not be retrieved from the current DataStructure data:\n" . format_data($self->get_request_data)); |
| return; |
| } |
| } |
| |
| if ($imagerevision_info) { |
| my $imagerevision_id = $imagerevision_info->{id}; |
| notify($ERRORS{'DEBUG'}, 0, "retrieved data for imagerevision ID: $imagerevision_id"); |
| $self->request_data->{reservation}{$self->reservation_id}{imagerevision} = $imagerevision_info; |
| } |
| else { |
| Exception::Class::Base->throw(error => "DataStructure object could not be initialized, failed to retrieve imagerevision data"); |
| return; |
| } |
| |
| my $image_id = $imagerevision_info->{imageid}; |
| if (!defined($image_id)) { |
| Exception::Class::Base->throw(error => "DataStructure object could not be initialized, failed to retrieve image ID from the imagerevision data:\n" . format_data($imagerevision_info)); |
| return; |
| } |
| |
| my $image_info = get_image_info($image_id); |
| if ($image_info) { |
| notify($ERRORS{'DEBUG'}, 0, "retrieved data for image ID: $image_id"); |
| $self->request_data->{reservation}{$self->reservation_id}{image} = $image_info; |
| } |
| else { |
| Exception::Class::Base->throw(error => "DataStructure object could not be initialized, failed to retrieve data for image ID: " . $self->image_id); |
| return; |
| } |
| } |
| |
| return 1; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 automethod |
| |
| Parameters : $show_warnings (optional) |
| Returns : Data based on the method name, 0 if method was not handled |
| Description : This subroutine is automatically invoked when an class method is |
| called on a DataStructure object but the method isn't explicitly |
| defined. Function names are mapped to data stored in the request |
| data hash. This subroutine returns the requested data. An |
| optional argument can be specified with a value of 1 to suppress |
| warnings if data is not initialized for the value requested. |
| |
| =cut |
| |
| sub _automethod : Automethod { |
| my $self = shift; |
| my @args = @_; |
| my $method_name = $_; |
| |
| # Make sure the function name begins with get_ or set_ |
| my $mode; |
| my $data_identifier; |
| if ($method_name =~ /^(get|set)_(.*)/) { |
| # $mode stores either 'get' or 'set', data stores the requested data |
| $mode = $1; |
| $data_identifier = $2; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "illegal subroutine name: $method_name"); |
| return sub { }; |
| } |
| |
| # Determines whether or not warnings are shown if data is not initialized |
| my $show_warnings = 1; |
| |
| # If set, make sure an argument was passed |
| my $set_data; |
| if ($mode =~ /set/ && defined $args[0]) { |
| $set_data = $args[0]; |
| } |
| elsif ($mode =~ /set/) { |
| notify($ERRORS{'WARNING'}, 0, "data structure $method_name function was called without an argument"); |
| return sub { }; |
| } |
| elsif ($mode =~ /get/ && defined $args[0] && !$args[0]) { |
| $show_warnings = 0; |
| } |
| |
| my $calling_subroutine = get_calling_subroutine(); |
| |
| # Check if the sub name is defined in the subroutine mappings hash |
| # Return if it isn't |
| if (!defined $SUBROUTINE_MAPPINGS{$data_identifier}) { |
| if ($calling_subroutine eq 'VCL::DataStructure::can') { |
| return; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "unsupported subroutine name: $method_name"); |
| return sub { }; |
| } |
| } |
| elsif ($calling_subroutine eq 'VCL::DataStructure::can') { |
| return sub { }; |
| } |
| |
| # Get the hash path out of the subroutine mappings hash |
| my $hash_path = $SUBROUTINE_MAPPINGS{$data_identifier}; |
| |
| # Replace RESERVATION_ID with the actual reservation ID if it exists in the hash path |
| my $reservation_id = $self->reservation_id; |
| $reservation_id = 'undefined' if !defined($reservation_id); |
| $hash_path =~ s/RESERVATION_ID/$reservation_id/; |
| |
| # Replace BLOCKREQUEST_ID with the actual blockrequest ID if it exists in the hash path |
| my $blockrequest_id = $self->blockrequest_id; |
| $blockrequest_id = 'undefined' if !defined($blockrequest_id); |
| $hash_path =~ s/BLOCKREQUEST_ID/$blockrequest_id/; |
| |
| # Replace BLOCKTIME_ID with the actual blocktime ID if it exists in the hash path |
| my $blocktime_id = $self->blocktime_id; |
| $blocktime_id = 'undefined' if !defined($blocktime_id); |
| $hash_path =~ s/BLOCKTIME_ID/$blocktime_id/; |
| |
| if ($mode =~ /get/) { |
| # Get the data from the request_data hash |
| # eval is required in order to interpolate the hash path before retrieving the data |
| my $key_defined = eval "defined $hash_path"; |
| |
| my $return_value; |
| |
| # If log or sublog data was requested and not yet populated, attempt to retrieve it |
| if (!$key_defined && $data_identifier =~ /^(log_|sublog_)/) { |
| notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve log data, requested data has not been initialized ($data_identifier)"); |
| |
| if ($self->get_log_data()) { |
| # Log data was retrieved, check if requested data is now populated |
| if (eval "defined $hash_path") { |
| $return_value = eval $hash_path; |
| notify($ERRORS{'DEBUG'}, 0, "log data was retrieved and corresponding data has been initialized for $method_name: $return_value"); |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "log data was retrieved but corresponding data has not been initialized for $method_name: $hash_path", $self->request_data) if $show_warnings; |
| return sub { }; |
| } |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "log data could not be retrieved"); |
| return sub { }; |
| } |
| } |
| elsif ($data_identifier =~ /^(management_node)/) { |
| # Get the management node info |
| # If no argument was specified get_management_node_info will return data for this management node |
| my $management_node_info_retrieved = get_management_node_info($args[0]); |
| unless ($management_node_info_retrieved) { |
| notify($ERRORS{'WARNING'}, 0, "failed to retrieve data for management node"); |
| return sub { }; |
| } |
| |
| # The normal reservation management node data is stored in $ENV->{management_node_info}->{<identifier>} |
| # We don't want to overwrite this, but want to temporarily store the data retrieved |
| # This allows the $hash_path mechanism to work without alterations |
| # Temporarily overwrite this data by using 'local', and set it to the data just retrieved |
| # Once the current scope is exited, $ENV->{management_node_info} will return to its original value |
| local $ENV->{management_node_info} = $management_node_info_retrieved; |
| |
| # Attempt to retrieve the value from the temporary data: $ENV->{management_node_info}->{KEY} |
| $return_value = eval $hash_path; |
| } |
| elsif (!$key_defined) { |
| if ($show_warnings && $hash_path !~ /(serverrequest|domain)/) { |
| notify($ERRORS{'WARNING'}, 0, "corresponding data has not been initialized for $method_name: $hash_path", $self->request_data); |
| } |
| return sub { }; |
| } |
| else { |
| # Just attempt to retrieve the value from the hash path |
| $return_value = eval $hash_path; |
| } |
| |
| if (!defined $return_value) { |
| if ($show_warnings && $method_name !~ /^(get_management_node_keys)$/) { |
| notify($ERRORS{'WARNING'}, 0, "corresponding data is undefined for $method_name: $hash_path"); |
| } |
| return sub { }; |
| } |
| |
| # Return the data |
| return sub {$return_value;}; |
| } ## end if ($mode =~ /get/) |
| elsif ($mode =~ /set/) { |
| eval $hash_path . ' = $set_data'; |
| |
| # Make sure the value was set in the hash |
| my $check_value = eval $hash_path; |
| if ($check_value eq $set_data) { |
| #notify($ERRORS{'DEBUG'}, 0, "data structure updated, hash path: $hash_path, data identifier: $data_identifier"); |
| return sub {1;}; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "data structure could not be updated, hash path: $hash_path, data identifier: $data_identifier, data:\n" . format_data($set_data)); |
| return sub {0;}; |
| } |
| } ## end elsif ($mode =~ /set/) [ if ($mode =~ /get/) |
| } ## end sub _automethod : |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_request_data (deprecated) |
| |
| Parameters : none |
| Returns : scalar |
| Description : Returns the request data hash. |
| |
| =cut |
| |
| sub get_request_data { |
| my $self = shift; |
| return $self->request_data; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 can |
| |
| Parameters : $function_name |
| Returns : boolean |
| Description : Determines if this module supports a particular function. |
| |
| =cut |
| |
| sub can { |
| my $self = shift; |
| |
| my $function_name = shift; |
| if (!defined($function_name)) { |
| notify($ERRORS{'WARNING'}, 0, "function name argument is not implemented"); |
| return; |
| } |
| |
| if ($self->SUPER::can($function_name)) { |
| #notify($ERRORS{'DEBUG'}, 0, "function is implemented: $function_name"); |
| return 1; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "function is NOT implemented: $function_name"); |
| return 0; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 refresh |
| |
| Parameters : none |
| Returns : true |
| Description : Retrieves current request info from the database and replaces the |
| data contained in this object. |
| |
| =cut |
| |
| sub refresh { |
| my $self = shift; |
| |
| # Save the current state names |
| my $request_id = $self->get_request_id(); |
| my $request_state_name = $self->get_request_state_name(); |
| my $request_laststate_name = $self->get_request_laststate_name(); |
| |
| # Get the full set of database data for this request |
| if (my $request_info = get_request_info($request_id)) { |
| notify($ERRORS{'DEBUG'}, 0, "retrieved current request information from database for request $request_id"); |
| |
| # Set the state names in the newly retrieved hash to their original values |
| $request_info->{state}{name} = $request_state_name; |
| $request_info->{laststate}{name} = $request_laststate_name; |
| |
| # Replace the request data for this DataStructure object |
| $self->refresh_request_data($request_info); |
| notify($ERRORS{'DEBUG'}, 0, "updated DataStructure object with current request information from database"); |
| |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "could not retrieve current request information from database"); |
| return; |
| } |
| |
| return 1; |
| } ## end sub refresh |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_blockrequest_data (deprecated) |
| |
| Parameters : none |
| Returns : scalar |
| Description : Returns the block request data hash. |
| |
| =cut |
| |
| sub get_blockrequest_data { |
| my $self = shift; |
| |
| # Check to make sure block request ID is defined |
| if (!$self->blockrequest_id) { |
| notify($ERRORS{'WARNING'}, 0, "failed to return block request data hash, block request ID is not defined"); |
| return; |
| } |
| |
| # Check to make sure block request ID is defined |
| if (!$self->blockrequest_data) { |
| notify($ERRORS{'WARNING'}, 0, "block request data hash is not defined"); |
| return; |
| } |
| |
| # Check to make sure block request data is defined for the ID |
| if (!$self->blockrequest_data->{$self->blockrequest_id}) { |
| notify($ERRORS{'WARNING'}, 0, "block request data hash is not defined for block request $self->blockrequest_id"); |
| return; |
| } |
| |
| # Data is there, return it |
| return $self->blockrequest_data->{$self->blockrequest_id}; |
| } ## end sub get_blockrequest_data |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_reservation_count |
| |
| Parameters : none |
| Returns : scalar |
| Description : Returns the number of reservations for the request |
| associated with this reservation's DataStructure object. |
| |
| =cut |
| |
| sub get_reservation_count { |
| my $self = shift; |
| |
| my $reservation_count = scalar keys %{$self->request_data->{reservation}}; |
| return $reservation_count; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_reservation_ids |
| |
| Parameters : none |
| Returns : array |
| Description : Returns an array containing all reservation IDs for the current |
| request sorted from lowest to highest. |
| |
| =cut |
| |
| sub get_reservation_ids { |
| my $self = shift; |
| |
| my @reservation_ids = sort {$a <=> $b} keys %{$self->request_data->{reservation}}; |
| return @reservation_ids; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_child_reservation_ids |
| |
| Parameters : none |
| Returns : array |
| Description : Returns an array containing all child reservation IDs for the |
| current request sorted from lowest to highest. The parent |
| reservation id is omitted. |
| |
| =cut |
| |
| sub get_child_reservation_ids { |
| my $self = shift; |
| my $parent_reservation_id = $self->get_parent_reservation_id(); |
| my @reservation_ids = $self->get_reservation_ids(); |
| my @child_reservation_ids = grep { $_ ne $parent_reservation_id } @reservation_ids; |
| return @child_reservation_ids; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_parent_reservation_id |
| |
| Parameters : none |
| Returns : integer |
| Description : Returns the reservation ID for the parent reservation of a |
| cluster request. |
| |
| =cut |
| |
| sub get_parent_reservation_id { |
| my $self = shift; |
| |
| # The parent reservation has the lowest ID |
| return min $self->get_reservation_ids(); |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 is_parent_reservation |
| |
| Parameters : none |
| Returns : scalar, either 1 or 0 |
| Description : This subroutine returns 1 if this is the parent reservation for |
| the request or if the request has 1 reservation associated with |
| it. It returns 0 if there are multiple reservations associated |
| with the request and this reservation is a child. |
| |
| =cut |
| |
| sub is_parent_reservation { |
| my $self = shift; |
| |
| my $reservation_id = $self->get_reservation_id(); |
| my $parent_reservation_id = $self->get_parent_reservation_id(); |
| |
| if ($reservation_id == $parent_reservation_id) { |
| notify($ERRORS{'DEBUG'}, 0, "this is the parent reservation"); |
| return 1; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "this is a child reservation, parent reservation ID for this request: $parent_reservation_id"); |
| return 0; |
| } |
| } ## end sub is_parent_reservation |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_reservation_data |
| |
| Parameters : reservation id |
| Returns : DataStructure object of specific reservation |
| Description : |
| |
| =cut |
| |
| sub get_reservation_data { |
| my $self = shift; |
| my $reservation_id = shift; |
| |
| # Check to make sure reservation ID was passed |
| if (!$reservation_id) { |
| notify($ERRORS{'WARNING'}, 0, "reservation ID was not specified, useless use of this subroutine, returning self"); |
| return $self; |
| } |
| |
| # Make sure reservation ID is an integer |
| if ($reservation_id !~ /^\d+$/) { |
| notify($ERRORS{'CRITICAL'}, 0, "reservation ID must be an integer, invalid value was passed: $reservation_id"); |
| return; |
| } |
| |
| # Check if the reservation ID is the same as the one for this object |
| if ($reservation_id == $self->reservation_id) { |
| notify($ERRORS{'WARNING'}, 0, "reservation ID the same as this object's, useless use of this subroutine, returning self"); |
| return $self; |
| } |
| |
| # Make sure reservation ID exists for this request |
| my @reservation_ids = $self->get_reservation_ids(); |
| if (!grep($reservation_id, @reservation_ids)) { |
| notify($ERRORS{'WARNING'}, 0, "reservation ID does not exist for this request: $reservation_id"); |
| return; |
| } |
| |
| # Get a new data structure object |
| my $sibling_data_structure; |
| eval {$sibling_data_structure = new VCL::DataStructure({request_data => $self->request_data, reservation_id => $reservation_id});}; |
| if (my $e = Exception::Class::Base->caught()) { |
| notify($ERRORS{'CRITICAL'}, 0, "unable to create sibling DataStructure object" . $e->message); |
| return; |
| } |
| |
| return $sibling_data_structure; |
| } ## end sub get_reservation_data |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 set_reservation_remote_ip |
| |
| Parameters : $remote_ip |
| Returns : boolean |
| Description : Updates the reservation.remoteIP value in the database. |
| |
| =cut |
| |
| sub set_reservation_remote_ip { |
| my $self = shift; |
| my $reservation_id = $self->get_reservation_id(); |
| |
| my $remote_ip = shift; |
| |
| # Check to make sure reservation ID was passed |
| if (!$remote_ip) { |
| notify($ERRORS{'WARNING'}, 0, "remote IP address argument was not specified"); |
| return 0; |
| } |
| |
| # Set the current value in the request data hash |
| $self->request_data->{reservation}{$reservation_id}{remoteIP} = $remote_ip; |
| |
| my $update_statement = <<EOF; |
| UPDATE |
| reservation |
| SET |
| remoteIP = '$remote_ip' |
| WHERE |
| id = '$reservation_id' |
| EOF |
| |
| # Call the database execute subroutine |
| if (database_execute($update_statement)) { |
| notify($ERRORS{'OK'}, 0, "remote IP updated to $remote_ip for reservation $reservation_id"); |
| return 1; |
| } |
| else { |
| notify($ERRORS{'CRITICAL'}, 0, "failed to update remote IP to $remote_ip for reservation $reservation_id"); |
| return 0; |
| } |
| } ## end sub set_reservation_remote_ip |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_reservation_remote_ip |
| |
| Parameters : none |
| Returns : string |
| Description : |
| |
| =cut |
| |
| sub get_reservation_remote_ip { |
| my $self = shift; |
| my $reservation_id = $self->get_reservation_id(); |
| |
| # Create the select statement |
| my $select_statement = " |
| SELECT |
| remoteIP |
| FROM |
| reservation |
| WHERE |
| id = $reservation_id |
| "; |
| |
| # Call the database select subroutine |
| my @selected_rows = database_select($select_statement); |
| |
| # Check to make sure 1 row was returned |
| if (scalar @selected_rows == 0) { |
| notify($ERRORS{'WARNING'}, 0, "failed to get reservation remote IP for reservation $reservation_id, zero rows were returned from database select"); |
| return; |
| } |
| elsif (scalar @selected_rows > 1) { |
| notify($ERRORS{'WARNING'}, 0, "failed to get reservation remote IP for reservation $reservation_id, " . scalar @selected_rows . " rows were returned from database select"); |
| return; |
| } |
| |
| # Get the single returned row |
| # It contains a hash |
| my $remote_ip; |
| |
| # Return 0 if the column isn't set |
| if (!defined $selected_rows[0]{remoteIP}) { |
| #notify($ERRORS{'OK'}, 0, "reservation remote IP is not defined"); |
| return 0; |
| } |
| |
| # Make sure we return 0 if remote IP is blank |
| elsif ($selected_rows[0]{remoteIP} eq '') { |
| #notify($ERRORS{'OK'}, 0, "reservation remote IP is not set"); |
| return 0; |
| } |
| |
| # Set the current value in the request data hash |
| $self->request_data->{reservation}{$reservation_id}{remoteIP} = $selected_rows[0]{remoteIP}; |
| |
| notify($ERRORS{'DEBUG'}, 0, "retrieved remote IP for reservation $reservation_id: $selected_rows[0]{remoteIP}"); |
| return $selected_rows[0]{remoteIP}; |
| } ## end sub get_reservation_remote_ip |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_state_name |
| |
| Parameters : none |
| Returns : string |
| Description : Returns either the request state name or 'blockrequest'. Useful |
| for vcld when make_new_child needs to figure out which module |
| to call. Without this subroutine, it would need to include |
| if statement and then call get_request_state_name or hack the |
| name if it's processing a block request; |
| |
| =cut |
| |
| sub get_state_name { |
| my $self = shift; |
| |
| if ($self->blockrequest_id) { |
| return 'blockrequest'; |
| } |
| elsif ($self->request_data->{state}{name}) { |
| return $self->request_data->{state}{name}; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "blockrequest ID is not set and request state name is undefined"); |
| return; |
| } |
| } ## end sub get_state_name |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_next_image_data_structure |
| |
| Parameters : none |
| Returns : array |
| Description : called mainly from reclaim module. Refreshes predictive load |
| module information from database, loads module and calls next_image. |
| |
| =cut |
| |
| sub get_next_image_data_structure { |
| my $self = shift; |
| |
| # Get the current image data in case something goes wrong |
| my $image_name = $self->get_image_name(); |
| my $image_id = $self->get_image_id(); |
| my $imagerevision_id = $self->get_imagerevision_id(); |
| |
| # Assemble an array with the current image information |
| # This will be returned if the predictive method fails |
| my @current_image; |
| if ($image_name && $image_id && $imagerevision_id) { |
| @current_image = ("reload", $image_name, $image_id, $imagerevision_id); |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "unable to obtain current image information"); |
| @current_image = (); |
| } |
| |
| #collect predictive reload information from database. |
| my $computer_predictive_module_id = $self->get_computer_predictive_module_id(); |
| if (!$computer_predictive_module_id) { |
| notify($ERRORS{'CRITICAL'}, 0, "unable to obtain management node info for this node, returning current reservation image information"); |
| return @current_image; |
| } |
| |
| #update ENV in case other modules need to know |
| my $management_node_info = get_management_node_info(); |
| |
| $management_node_info->{predictivemoduleid} = $self->get_computer_predictive_module_id(); |
| $management_node_info->{predictive_name} = $self->get_computer_predictive_module_name(); |
| $management_node_info->{predictive_prettyname} = $self->get_computer_predictive_pretty_name(); |
| $management_node_info->{predictive_description} = $self->get_computer_predictive_module_description(); |
| $management_node_info->{predictive_perlpackage} = $self->get_computer_predictive_module_perl_package(); |
| |
| my $predictive_perl_package = $self->get_computer_predictive_module_perl_package(); |
| |
| my @nextimage; |
| |
| if ($predictive_perl_package) { |
| notify($ERRORS{'OK'}, 0, "attempting to load predictive loading module: $predictive_perl_package"); |
| |
| eval "use $predictive_perl_package"; |
| |
| if ($EVAL_ERROR) { |
| notify($ERRORS{'WARNING'}, 0, "$predictive_perl_package module could not be loaded"); |
| notify($ERRORS{'OK'}, 0, "returning current reservation image information"); |
| return @current_image; |
| } |
| if (my $predictor = ($predictive_perl_package)->new({data_structure => $self})) { |
| @nextimage = $predictor->get_next_image(); |
| notify($ERRORS{'OK'}, 0, ref($predictor) . " predictive loading object successfully created"); |
| notify($ERRORS{'OK'}, 0, "predictive loading module retreived image information: @nextimage"); |
| if (scalar(@nextimage) == 4) { |
| return @nextimage; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "predictive loading module failed to retrieve image information, returning current reservation image information"); |
| return @current_image; |
| } |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "predictive loading object could not be created, returning current reservation image information"); |
| return @current_image; |
| } |
| } ## end if ($predictive_perl_package) |
| else { |
| notify($ERRORS{'OK'}, 0, "predictive loading module not loaded, Perl package is not defined, returning current reservation image information"); |
| return @current_image; |
| } |
| } |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 print_data |
| |
| Parameters : |
| Returns : |
| Description : |
| |
| =cut |
| |
| sub print_data { |
| my $self = shift; |
| |
| my $request_data = format_data($self->request_data, 'request'); |
| my $management_node_info = format_data($ENV->{management_node_info}, 'management_node'); |
| |
| notify($ERRORS{'OK'}, 0, "request data:\n$request_data\n\nmanagement node info:\n$management_node_info"); |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 print_subroutines |
| |
| Parameters : |
| Returns : |
| Description : |
| |
| =cut |
| |
| sub print_subroutines { |
| my $self = shift; |
| |
| my $output; |
| foreach my $mapping_key (sort keys %SUBROUTINE_MAPPINGS) { |
| my $mapping_value = $SUBROUTINE_MAPPINGS{$mapping_key}; |
| $mapping_value =~ s/^\$self->request_data->/\%request/; |
| $mapping_value =~ s/^\$ENV\{management_node_info\}/\%management_node/; |
| $output .= "get_$mapping_key() : $mapping_value\n"; |
| } |
| |
| notify($ERRORS{'OK'}, 0, "valid subroutines:\n$output"); |
| } ## end sub print_subroutines |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_log_data |
| |
| Parameters : none |
| Returns : hash reference |
| Description : Retrieves data from the log and sublog tables for the log ID |
| either specified via an argument or the log ID for the |
| reservation represented by the DataStructure object. |
| |
| =cut |
| |
| sub get_log_data { |
| my $self = shift; |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'WARNING'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| my $current_reservation_id = $self->get_reservation_id(); |
| my $request_id = $self->get_request_id(); |
| my @reservation_ids = $self->get_reservation_ids(); |
| |
| # Retrieve log info for all reservations |
| my $log_info = get_request_log_info($request_id) || return; |
| |
| $self->request_data->{log} = $log_info; |
| |
| # Get a mapping between computer to reservation IDs |
| # TODO: add sublog.reservationid column, this will no longer be necessary |
| my $computer_reservation_ids = {}; |
| for my $reservation_id (@reservation_ids) { |
| my $reservation_data; |
| if ($reservation_id eq $current_reservation_id) { |
| $reservation_data = $self; |
| } |
| else { |
| $reservation_data = $self->get_reservation_data($reservation_id); |
| } |
| if (!$reservation_data) { |
| notify($ERRORS{'WARNING'}, 0, "DataStructure object could not be retrieved for reservation $reservation_id"); |
| next; |
| } |
| |
| my $reservation_computer_id = $reservation_data->get_computer_id(); |
| if (!$reservation_computer_id) { |
| notify($ERRORS{'WARNING'}, 0, "computer ID could not be determined for reservation $reservation_id"); |
| next; |
| } |
| |
| $computer_reservation_ids->{$reservation_computer_id} = $reservation_id; |
| } |
| |
| for my $sublog_id (keys %{$log_info->{sublog}}) { |
| my $sublog_computer_id = $log_info->{sublog}{$sublog_id}{computerid}; |
| if (!$sublog_computer_id) { |
| notify($ERRORS{'WARNING'}, 0, "computer ID is not defined for sublog $sublog_id:\n" . format_data($log_info)); |
| next; |
| } |
| |
| my $reservation_id = $computer_reservation_ids->{$sublog_computer_id}; |
| if (!$reservation_id) { |
| notify($ERRORS{'WARNING'}, 0, "computer ID is set to $sublog_computer_id for sublog ID $sublog_id, no reservation assigned to this request is assigned that computer ID"); |
| next; |
| } |
| |
| $self->request_data->{reservation}{$reservation_id}{SUBLOG_ID} = $sublog_id; |
| $self->request_data->{reservation}{$reservation_id}{sublog} = $log_info->{sublog}{$sublog_id}; |
| } |
| |
| notify($ERRORS{'DEBUG'}, 0, "updated DataStructure object with log and sublog data"); |
| return $self->request_data->{log}; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_computer_private_ip_address |
| |
| Parameters : $suppress_warning (optional) |
| Returns : string |
| Description : Retrieves the private IP address for a computer. If an address is |
| already stored in the DataStructure object, then that address is |
| returned. If no address is stored, null is returned and a warning |
| message is displayed in the log file. This can be suppressed via |
| the argument. |
| |
| =cut |
| |
| sub get_computer_private_ip_address { |
| my $self = shift; |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'WARNING'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| my $suppress_warning = shift; |
| |
| my $computer_id = $self->get_computer_id(); |
| my $computer_hostname = $self->get_computer_hostname(); |
| if (!defined($computer_id) || !defined($computer_hostname)) { |
| notify($ERRORS{'WARNING'}, 0, "computer ID and hostname are not stored in this DataStructure object"); |
| return; |
| } |
| |
| # Check if the IP address is already stored |
| my $data_structure_private_ip_address = $self->request_data->{reservation}{$self->reservation_id}{computer}{privateIPaddress}; |
| my $env_private_ip_address = $ENV->{computer_private_ip_address}->{$computer_id}; |
| |
| # Check if private IP adddress is stored in %ENV and differs from this object's data |
| if ($data_structure_private_ip_address) { |
| if ($env_private_ip_address) { |
| if ($env_private_ip_address =~ /null/i) { |
| notify($ERRORS{'DEBUG'}, 0, "private IP address for $computer_hostname ($computer_id) is stored in this object $data_structure_private_ip_address, \%ENV is set to null, deleting private IP address from this object"); |
| delete $self->request_data->{reservation}{$self->reservation_id}{computer}{privateIPaddress}; |
| return; |
| } |
| elsif ($data_structure_private_ip_address eq $env_private_ip_address) { |
| notify($ERRORS{'DEBUG'}, 0, "private IP address for $computer_hostname ($computer_id) stored in this object matches IP address stored in \%ENV: $data_structure_private_ip_address"); |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "private IP address for $computer_hostname ($computer_id) stored in this object $data_structure_private_ip_address does not match IP address stored in \%ENV, updating private IP address stored in this object: $env_private_ip_address"); |
| $self->request_data->{reservation}{$self->reservation_id}{computer}{privateIPaddress} = $env_private_ip_address; |
| } |
| return $env_private_ip_address; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "returning private IP address of $computer_hostname ($computer_id) already stored in this DataStructure object: $data_structure_private_ip_address"); |
| return $data_structure_private_ip_address; |
| } |
| } |
| else { |
| if ($env_private_ip_address && $env_private_ip_address !~ /null/i) { |
| notify($ERRORS{'DEBUG'}, 0, "private IP address for $computer_hostname ($computer_id) is not stored in this object but is stored in \%ENV, setting private IP address in this object: $env_private_ip_address"); |
| $self->request_data->{reservation}{$self->reservation_id}{computer}{privateIPaddress} = $env_private_ip_address; |
| return $env_private_ip_address; |
| } |
| else { |
| if ($suppress_warning) { |
| notify($ERRORS{'DEBUG'}, 0, "private IP address of $computer_hostname ($computer_id) is not set in this object"); |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "private IP address of $computer_hostname ($computer_id) is not set in this object") |
| } |
| return; |
| } |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 set_computer_private_ip_address |
| |
| Parameters : $private_ip_address |
| Returns : boolean |
| Description : Sets the computer private IP address in the DataStructure. If the |
| IP address argument is different than the value currently stored |
| in the DataStructure object, the database is updated. |
| |
| =cut |
| |
| sub set_computer_private_ip_address { |
| my $self = shift; |
| |
| # Check if subroutine was called as an object method |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| my $private_ip_address_argument = shift; |
| if (!$private_ip_address_argument) { |
| notify($ERRORS{'WARNING'}, 0, "computer private IP address argument was not supplied"); |
| return; |
| } |
| elsif ($private_ip_address_argument !~ /null/i && !is_valid_ip_address($private_ip_address_argument)) { |
| notify($ERRORS{'WARNING'}, 0, "computer private IP address argument is not valid: '$private_ip_address_argument'"); |
| return; |
| } |
| |
| my $computer_id = $self->get_computer_id(); |
| if (!defined($computer_id)) { |
| notify($ERRORS{'WARNING'}, 0, "computer ID is not stored in this DataStructure object"); |
| return; |
| } |
| |
| my $computer_hostname = $self->get_computer_hostname(); |
| if (!$computer_hostname) { |
| notify($ERRORS{'WARNING'}, 0, "computer hostname is not stored in this DataStructure object"); |
| return; |
| } |
| |
| # Update this DataStructure object |
| if ($private_ip_address_argument =~ /null/i) { |
| delete $self->request_data->{reservation}{$self->reservation_id}{computer}{privateIPaddress}; |
| } |
| else { |
| $self->request_data->{reservation}{$self->reservation_id}{computer}{privateIPaddress} = $private_ip_address_argument; |
| } |
| |
| # Update the database |
| if ($computer_id && !update_computer_private_ip_address($computer_id, $private_ip_address_argument)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to update private IP address of $computer_hostname to $private_ip_address_argument, unable to update the database"); |
| return; |
| } |
| |
| notify($ERRORS{'DEBUG'}, 0, "private IP address of $computer_hostname set to $private_ip_address_argument"); |
| return 1; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_image_affiliation_name |
| |
| Parameters : none |
| Returns : If successful: string containing affiliation name |
| If failed: false |
| Description : This subroutine determines the affiliation name for the image |
| assigned to the reservation. |
| The image affiliation is based on the affiliation of the image |
| owner. |
| |
| =cut |
| |
| sub get_image_affiliation_name { |
| my $self = shift; |
| |
| # Check if subroutine was called as an object method |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| # Get the image owner id in order to determine the image affiliation |
| my $image_owner_id = $self->get_image_ownerid(); |
| notify($ERRORS{'DEBUG'}, 0, "image owner id: $image_owner_id"); |
| unless ($image_owner_id) { |
| notify($ERRORS{'WARNING'}, 0, "unable to determine image owner id in order to determine image affiliation"); |
| return; |
| } |
| |
| # Get the data for the user who owns the image |
| my $image_owner_data = get_user_info($image_owner_id); |
| unless ($image_owner_data) { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve image owner data in order to determine image affiliation"); |
| return; |
| } |
| |
| # Get the affiliation name from the user data hash |
| my $image_affiliation_name = $image_owner_data->{affiliation}{name}; |
| unless ($image_affiliation_name) { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve image owner affiliation name"); |
| return; |
| } |
| |
| return $image_affiliation_name; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_image_affiliation_id |
| |
| Parameters : none |
| Returns : If successful: string containing affiliation id |
| If failed: false |
| Description : This subroutine determines the affiliation id for the image |
| assigned to the reservation. |
| The image affiliation is based on the affiliation of the image |
| owner. |
| |
| =cut |
| |
| sub get_image_affiliation_id { |
| my $self = shift; |
| |
| # Check if subroutine was called as an object method |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| # Get the image owner id in order to determine the image affiliation |
| my $image_owner_id = $self->get_image_ownerid(); |
| notify($ERRORS{'DEBUG'}, 0, "image owner id: $image_owner_id"); |
| if (!defined($image_owner_id)) { |
| notify($ERRORS{'WARNING'}, 0, "unable to determine image owner id in order to determine image affiliation"); |
| return; |
| } |
| |
| # Get the data for the user who owns the image |
| my $image_owner_data = get_user_info($image_owner_id); |
| unless ($image_owner_data) { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve image owner data in order to determine image affiliation"); |
| return; |
| } |
| |
| # Get the affiliation id from the user data hash |
| my $image_affiliation_id = $image_owner_data->{affiliation}{id}; |
| unless ($image_affiliation_id) { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve image owner affiliation id"); |
| return; |
| } |
| |
| return $image_affiliation_id; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 is_blockrequest |
| |
| Parameters : none |
| Returns : If DataStructure contains blockrequest data: true |
| If DataStructure does not contain blockrequest data: false |
| Description : This subroutine determines whether or not the DataStructure |
| contains data for a blockrequest. |
| |
| =cut |
| |
| sub is_blockrequest { |
| my $self = shift; |
| |
| # Check if subroutine was called as an object method |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| # Check if reservation_id has been set, return 1 or 0 based on that |
| if ($self->blockrequest_id) { |
| return 1; |
| } |
| else { |
| return 0; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 is_server_request |
| |
| Parameters : none |
| Returns : |
| Description : This subroutine determines whether or not the DataStructure |
| contains data for a server request. |
| |
| =cut |
| |
| sub is_server_request { |
| my $self = shift; |
| |
| # Check if subroutine was called as an object method |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| return $self->get_server_request_id() ? 1 : 0; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_management_node_public_default_gateway |
| |
| Parameters : none |
| Returns : If successful: string containing IP address |
| If failed: false |
| Description : Returns the management node's default gateway IP address. This |
| subroutine will return the address configured on the "GATEWAY=" |
| line in the vcld.conf file if configured. |
| |
| Otherwise it uses the "route -n" command and attempts to |
| locate a single line beginning with 0.0.0.0. |
| |
| If it fails to determine the default gateway using the route |
| command, the dhcpd.conf file is checked for an "option routers" |
| line containing a valid public IP address. |
| |
| =cut |
| |
| sub get_management_node_public_default_gateway { |
| my $default_gateway; |
| |
| # Attempt to retrieve the default gateway explicitly configured for this management node |
| my $management_node_info = get_management_node_info(); |
| if ($management_node_info) { |
| $default_gateway = $management_node_info->{PUBLIC_DEFAULT_GATEWAY}; |
| if ($default_gateway && is_valid_ip_address($default_gateway)) { |
| notify($ERRORS{'DEBUG'}, 0, "returning default gateway configured for management node: $default_gateway"); |
| return $default_gateway; |
| } |
| } |
| |
| # Attempt to retrieve the gateway from the route command |
| my ($route_exit_status, $route_output) = run_command('route -n', 1); |
| if ($route_output && (my @route_gateway_lines = grep(/^0.0.0.0/, @$route_output))) { |
| if (scalar @route_gateway_lines == 1) { |
| ($default_gateway) = $route_gateway_lines[0] =~ /^[\d\.]+\s+([\d\.]+)/; |
| if (is_valid_ip_address($default_gateway)) { |
| notify($ERRORS{'DEBUG'}, 0, "returning default gateway from route command: $default_gateway"); |
| return $default_gateway; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "unable to determine default gateway valid IP address from route command output:\n" . join("\n", @route_gateway_lines)); |
| } |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "multiple default gateway lines found in route command output:\n" . join("\n", @route_gateway_lines)); |
| } |
| } |
| |
| # Attempt to retrieve the gateway from the "option routers" line in dhcpd.conf |
| my @dhcpd_conf_lines = read_file_to_array('/etc/dhcpd.conf'); |
| if (@dhcpd_conf_lines) { |
| my @option_routers_lines = grep(/\s*[^#]\s*option\s+routers/, @dhcpd_conf_lines); |
| notify($ERRORS{'DEBUG'}, 0, "dhcpd.conf option routers lines:\n" . join("\n", @option_routers_lines)); |
| |
| # Store public IP addresses found on "option routers" lines as hash keys to ignore duplicates |
| my %public_option_routers_addresses; |
| |
| # Loop through any "option routers" lines found in dhcpd.conf |
| for my $option_routers_line (@option_routers_lines) { |
| # Extract the IP address from the "option routers" line |
| my ($option_routers_ip) = $option_routers_line =~ /option\s+routers\s+([\d\.]+)/; |
| |
| # Check if IP address was found, is valid, and is public |
| if (!$option_routers_ip) { |
| notify($ERRORS{'DEBUG'}, 0, "option routers line does not contain an IP address: $option_routers_line"); |
| next; |
| } |
| if (!is_valid_ip_address($option_routers_ip)) { |
| notify($ERRORS{'DEBUG'}, 0, "option routers line does not contain a valid IP address: $option_routers_line"); |
| next; |
| } |
| if (!is_public_ip_address($option_routers_ip)) { |
| notify($ERRORS{'DEBUG'}, 0, "option routers line contains a non-public address: $option_routers_line"); |
| next; |
| } |
| notify($ERRORS{'DEBUG'}, 0, "public option routers IP address found in dhcpd.conf: $option_routers_ip"); |
| $public_option_routers_addresses{$option_routers_ip} = 1; |
| } |
| |
| # Check if only 1 "option routers" line was found containing a valid public IP address |
| if (scalar keys(%public_option_routers_addresses) == 1) { |
| my $default_gateway = (keys(%public_option_routers_addresses))[0]; |
| notify($ERRORS{'DEBUG'}, 0, "returning default gateway found in dhcpd.conf: $default_gateway"); |
| return $default_gateway; |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "multiple public option routers IP addresses found in dhcpd.conf: " . keys(%public_option_routers_addresses)); |
| } |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve dhcpd.conf contents"); |
| } |
| |
| return; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_image_domain_dns_servers |
| |
| Parameters : none |
| Returns : array |
| Description : Returns an array containing the addresses of the Active Directory |
| domain DNS servers configured for the image. |
| |
| =cut |
| |
| sub get_image_domain_dns_servers { |
| my $self = shift; |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| my $reservation_id = $self->reservation_id; |
| my $dns_servers_array_ref = $self->request_data->{reservation}{$reservation_id}{image}{imagedomain}{dnsServers}; |
| if (!$dns_servers_array_ref) { |
| notify($ERRORS{'DEBUG'}, 0, "no Active Directory domain DNS server addresses are configured for the image"); |
| return (); |
| } |
| return @$dns_servers_array_ref |
| } |
| |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_management_node_public_dns_servers |
| |
| Parameters : none |
| Returns : If successful: array containing IP addresses |
| If failed: false |
| Description : Returns an array containing the addresses of the public DNS |
| servers configured for the management node. |
| |
| =cut |
| |
| sub get_management_node_public_dns_servers { |
| # Attempt to retrieve the DNS server addresses configured for this management node |
| my $management_node_info = get_management_node_info(); |
| if (!$management_node_info) { |
| notify($ERRORS{'WARNING'}, 0, "unable to determine public DNS servers, management node information could not be retrieved"); |
| return; |
| } |
| |
| my $dns_address_string = $management_node_info->{PUBLIC_DNS_SERVER}; |
| if (!$dns_address_string) { |
| notify($ERRORS{'DEBUG'}, 0, "no public DNS server addresses are configured for the management node"); |
| return (); |
| } |
| |
| return split(/\s*[,;]\s*/, $dns_address_string); |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_management_node_identity_key_paths |
| |
| Parameters : none |
| Returns : If successful: array containing paths to SSH identity keys |
| If failed: false |
| Description : Returns an array containing the paths to SSH identity keys |
| configured for the management node. |
| |
| =cut |
| |
| sub get_management_node_identity_key_paths { |
| my $management_node_info = get_management_node_info(); |
| if (!$management_node_info) { |
| notify($ERRORS{'WARNING'}, 0, "unable to determine public management node identity key paths, management node information could not be retrieved"); |
| return; |
| } |
| |
| my $keys_string = $management_node_info->{keys}; |
| if (!$keys_string) { |
| return ('/etc/vcl/vcl.key'); |
| } |
| |
| return split(/\s*[,;]\s*/, $keys_string); |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_computer_state_name |
| |
| Parameters : computer name (optional |
| Returns : String containing state name for a particular computer |
| Description : Queries database for current computer state and returns the |
| state name. The database is queried rather than simply returning |
| the value in the data structure in case the computer state |
| changed by some other process after the reservation process |
| began. This is mainly done for safety in case the computer state |
| gets set to maintenance. |
| |
| =cut |
| |
| |
| sub get_computer_state_name { |
| my $self; |
| my $argument = shift; |
| my $computer_name; |
| |
| # Check if subroutine was called as an object method |
| if (ref($argument) && $argument->isa('VCL::DataStructure')) { |
| # Subroutine was called as an object method, check if an argument was specified |
| $self = $argument; |
| $argument = shift; |
| if ($argument) { |
| # Argument was specified, use this as the computer name |
| $computer_name = $argument; |
| } |
| else { |
| # Argument was not specified, get the computer short name for this reservation |
| $computer_name = $self->get_computer_short_name(); |
| } |
| } |
| elsif (ref($argument)) { |
| notify($ERRORS{'WARNING'}, 0, "subroutine was called with an illegal argument type: " . ref($argument)); |
| return; |
| } |
| else { |
| # Subroutine was not called as an object method |
| $computer_name = $argument; |
| } |
| |
| # Make sure the computer name was determined either from an argument or the request data |
| if (!$computer_name) { |
| notify($ERRORS{'WARNING'}, 0, "unable to determine computer name from argument or request data"); |
| return; |
| } |
| |
| # Create the select statement |
| my $select_statement = " |
| SELECT DISTINCT |
| state.name AS name |
| FROM |
| state, |
| computer |
| WHERE |
| computer.stateid = state.id |
| AND (computer.hostname LIKE '$computer_name.%' OR computer.hostname = '$computer_name') |
| "; |
| |
| # Call the database select subroutine |
| # This will return an array of one or more rows based on the select statement |
| my @selected_rows = database_select($select_statement); |
| |
| # Check to make sure 1 row was returned |
| if (scalar @selected_rows == 0) { |
| notify($ERRORS{'WARNING'}, 0, "zero rows were returned from database select"); |
| return (); |
| } |
| elsif (scalar @selected_rows > 1) { |
| notify($ERRORS{'WARNING'}, 0, scalar @selected_rows . " rows were returned from database select"); |
| return (); |
| } |
| |
| # Make sure we return undef if the column wasn't found |
| if (defined $selected_rows[0]{name}) { |
| my $computer_state_name = $selected_rows[0]{name}; |
| notify($ERRORS{'DEBUG'}, 0, "retrieved current state of computer $computer_name from the database: $computer_state_name"); |
| $self->set_computer_state_name($computer_state_name); |
| return $computer_state_name; |
| } |
| else { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve current state of computer $computer_name from the database"); |
| return undef; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_reservation_info_string |
| |
| Parameters : none |
| Returns : String |
| Description : Assembles a string containing reservation information for |
| debugging purposes. |
| |
| =cut |
| |
| sub get_reservation_info_string { |
| my $self = shift; |
| |
| # Check if subroutine was called as an object method |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| my $string; |
| |
| $string .= "management node: " . (defined($_ = $self->get_management_node_hostname(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "reservation PID: $PID\n"; |
| $string .= "parent vcld PID: " . (defined($_ = getppid()) ? $_ : '<undefined>') . "\n"; |
| |
| my $request_id = $self->get_request_id(0); |
| if ($request_id) { |
| $string .= "\n"; |
| |
| $string .= "request ID: $request_id\n"; |
| $string .= "reservation ID: " . (defined($_ = $self->get_reservation_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "request state/laststate: " . (defined($_ = $self->get_request_state_name(0)) ? $_ : '<undefined>') . "/" . (defined($_ = $self->get_request_laststate_name(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "request start time: " . (defined($_ = $self->get_request_start_time(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "request end time: " . (defined($_ = $self->get_request_end_time(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "for imaging: " . (defined($_ = $self->get_request_forimaging(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n"; |
| $string .= "log ID: " . (defined($_ = $self->get_request_log_id(0)) ? ($_ eq '0' ? 'none' : $_) : '<undefined>') . "\n"; |
| |
| my $reservation_count = $self->get_request_reservation_count(0); |
| if (defined($reservation_count) && $reservation_count > 1) { |
| $string .= "cluster reservation: yes\n"; |
| $string .= "reservation count: $reservation_count\n"; |
| $string .= "parent reservation: " . (defined($_ = $self->is_parent_reservation(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n"; |
| } |
| } |
| |
| my $blockrequest_id = $self->get_blockrequest_id(0); |
| if ($blockrequest_id) { |
| $string .= "\n"; |
| |
| $string .= "blockrequest: " . (defined($_ = $self->get_blockrequest_name(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "block request ID: $blockrequest_id\n"; |
| $string .= "blockrequest image ID: " . (defined($_ = $self->get_blockrequest_image_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "number of machines: " . (defined($_ = $self->get_blockrequest_number_machines(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "owner ID: " . (defined($_ = $self->get_blockrequest_owner_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "management node ID: " . (defined($_ = $self->get_blockrequest_management_node_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "processing flag: " . (defined($_ = $self->get_blockrequest_processing(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "mode: " . (defined($_ = $self->get_blockrequest_mode(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "blocktime ID: " . (defined($_ = $self->get_blocktime_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "blocktime start: " . (defined($_ = $self->get_blocktime_start(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "blocktime end: " . (defined($_ = $self->get_blocktime_end(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "blocktime processed flag: " . (defined($_ = $self->get_blocktime_processed(0)) ? $_ : '<undefined>') . "\n"; |
| } |
| |
| my $computer_id = $self->get_computer_id(0); |
| if (defined($computer_id)) { |
| $string .= "\n"; |
| |
| $string .= "computer: " . (defined($_ = $self->get_computer_hostname(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "computer id: $computer_id\n"; |
| $string .= "computer type: " . (defined($_ = $self->get_computer_type(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "computer eth0 MAC address: " . (defined($_ = $self->get_computer_eth0_mac_address(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "computer eth1 MAC address: " . (defined($_ = $self->get_computer_eth1_mac_address(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "computer private IP address: " . (defined($_ = $self->get_computer_private_ip_address(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "computer public IP address: " . (defined($_ = $self->get_computer_public_ip_address(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "computer in block allocation: " . (defined($_ = is_inblockrequest($self->get_computer_id(0))) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n"; |
| $string .= "provisioning module: " . (defined($_ = $self->get_computer_provisioning_module_perl_package(0)) ? $_ : '<undefined>') . "\n"; |
| |
| if ($self->get_computer_type(0) eq 'virtualmachine') { |
| $string .= "\n"; |
| |
| $string .= "vm host: " . (defined($_ = $self->get_vmhost_hostname(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "vm host ID: " . (defined($_ = $self->get_vmhost_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "vm host computer ID: " . (defined($_ = $self->get_vmhost_computer_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "vm profile: " . (defined($_ = $self->get_vmhost_profile_name(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "vm profile VM path: " . (defined($_ = $self->get_vmhost_profile_vmpath(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "vm profile repository path: " . (defined($_ = $self->get_vmhost_profile_repository_path(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "vm profile datastore path: " . (defined($_ = $self->get_vmhost_profile_datastore_path(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "vm profile disk type: " . (defined($_ = $self->get_vmhost_profile_vmdisk(0)) ? $_ : '<undefined>') . "\n"; |
| } |
| } |
| |
| my $image_id = $self->get_image_id(0); |
| if (defined($image_id)) { |
| $string .= "\n"; |
| |
| $string .= "image: " . (defined($_ = $self->get_image_name(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "image display name: " . (defined($_ = $self->get_image_prettyname(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "image ID: $image_id\n"; |
| $string .= "image revision ID: " . (defined($_ = $self->get_imagerevision_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "image size: " . (defined($_ = $self->get_image_size(0)) ? $_ : '<undefined>') . " MB\n"; |
| $string .= "use Sysprep: " . (defined($_ = $self->get_imagemeta_sysprep(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n"; |
| $string .= "root access: " . (defined($_ = $self->get_imagemeta_rootaccess(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n"; |
| $string .= "image owner ID: " . (defined($_ = $self->get_image_ownerid(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "image owner affiliation: " . (defined($_ = $self->get_image_affiliation_name(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "image revision date created: " . (defined($_ = $self->get_imagerevision_date_created(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "image revision production: " . (defined($_ = $self->get_imagerevision_production(0)) ? ($_ ? 'yes' : 'no') : '<undefined>') . "\n"; |
| $string .= "OS module: " . (defined($_ = $self->get_image_os_module_perl_package(0)) ? $_ : '<undefined>') . "\n"; |
| |
| my $imagerevision_comments = $self->get_imagerevision_comments(0); |
| $string .= "image revision comments: $imagerevision_comments\n" if $imagerevision_comments; |
| } |
| |
| my $user_id = $self->get_user_id(0); |
| if (defined($user_id)) { |
| $string .= "\n"; |
| |
| $string .= "user: " . (defined($_ = $self->get_user_login_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "user name: " . (defined($_ = $self->get_user_firstname(0)) ? $_ : '<undefined>') . " " . (defined($_ = $self->get_user_lastname(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "user ID: " . (defined($_ = $self->get_user_id(0)) ? $_ : '<undefined>') . "\n"; |
| $string .= "user affiliation: " . (defined($_ = $self->get_user_affiliation_name(0)) ? $_ : '<undefined>') . "\n"; |
| } |
| |
| return $string; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_reservation_user_login_ids |
| |
| Parameters : none |
| Returns : array |
| Description : Returns an array containing the reservation user login IDs |
| (usernames). |
| |
| =cut |
| |
| |
| sub get_reservation_user_login_ids { |
| my $self = shift; |
| |
| my $reservation_user_info = $self->get_reservation_users(); |
| if (!$reservation_user_info) { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve reservation user login IDs, reservation user info is not populated in the request data"); |
| return; |
| } |
| |
| my @reservation_users = map { $reservation_user_info->{$_}{unityid} } keys %$reservation_user_info; |
| return @reservation_users; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_image_minram |
| |
| Parameters : none |
| Returns : integer |
| Description : Returns the larger of the image.minram and OS.minram values. |
| |
| =cut |
| |
| |
| sub get_image_minram { |
| my $self = shift; |
| # Check if subroutine was called as an object method |
| unless (ref($self) && $self->isa('VCL::DataStructure')) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine can only be called as a VCL::DataStructure module object method"); |
| return; |
| } |
| |
| my $reservation_id = $self->reservation_id; |
| my $image_minram = $self->request_data->{reservation}{$reservation_id}{image}{minram}; |
| my $os_minram = $self->request_data->{reservation}{$reservation_id}{image}{OS}{minram}; |
| my $minram = max ($image_minram, $os_minram); |
| #notify($ERRORS{'DEBUG'}, 0, "image minram: $image_minram, OS minram: $os_minram, result: $minram"); |
| return $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 information:\n$json"); |
| return $json; |
| } |
| |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_connect_method_info_matching_name |
| |
| Parameters : $regex_pattern |
| Returns : hash reference |
| Description : Checks the name of all connect methods mapped to the current |
| reservation's image revision. Returns info for all connect |
| methods with a connectmethod.name value matching the pattern |
| argument. This is useful for finding a particular connect method. |
| |
| For example: |
| $self->data->get_connect_method_info_matching_name('vmware'); |
| |
| A hash reference is returned. The only hash element would be |
| information about a "VMwareVNC" connect method. |
| |
| =cut |
| |
| sub get_connect_method_info_matching_name { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return; |
| } |
| |
| my $regex_pattern = shift; |
| if (!defined($regex_pattern)) { |
| notify($ERRORS{'WARNING'}, 0, "connect method name regex pattern argument was not supplied"); |
| return; |
| } |
| |
| my $matching_connect_method_info = {}; |
| |
| my $connect_method_info = $self->get_connect_methods(); |
| for my $connect_method_id (sort {$a <=> $b} keys %$connect_method_info) { |
| my $connect_method = $connect_method_info->{$connect_method_id}; |
| my $connect_method_name = $connect_method->{name}; |
| if ($connect_method_name =~ /$regex_pattern/i) { |
| $matching_connect_method_info->{$connect_method_id} = $connect_method; |
| } |
| } |
| |
| my $matching_count = scalar(keys %$matching_connect_method_info); |
| if (!$matching_count) { |
| notify($ERRORS{'DEBUG'}, 0, "no connect methods with name matching pattern '$regex_pattern' are mapped to image revision assigned to reservation"); |
| } |
| else { |
| notify($ERRORS{'DEBUG'}, 0, "found $matching_count connect method(s) with name matching pattern '$regex_pattern' mapped to image revision assigned to reservation:\n" . format_data($matching_connect_method_info)); |
| } |
| return $matching_connect_method_info; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_connect_method_protocol_port_array |
| |
| Parameters : none |
| Returns : array |
| Description : Processes all of the connect methods assigned to the image |
| revision and constructs an simpler array for easier processing. |
| An array is returned. Each array element is an array reference |
| with exactly 2 elements, a protocol name and port number: |
| ( |
| ["tcp", 22], |
| ["tcp", 3389], |
| ["udp", 3389], |
| ) |
| |
| =cut |
| |
| sub get_connect_method_protocol_port_array { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| my @protocol_port_array; |
| |
| my $connect_method_info = $self->get_connect_methods(); |
| for my $connect_method_id (sort keys %{$connect_method_info}) { |
| for my $connect_method_port_id (keys %{$connect_method_info->{$connect_method_id}{connectmethodport}}) { |
| my $protocol = $connect_method_info->{$connect_method_id}{connectmethodport}{$connect_method_port_id}{protocol}; |
| my $port = $connect_method_info->{$connect_method_id}{connectmethodport}{$connect_method_port_id}{port}; |
| push @protocol_port_array, [lc($protocol), $port], |
| } |
| } |
| return @protocol_port_array; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_user_affiliation_sitewwwaddress |
| |
| Parameters : none |
| Returns : string |
| Description : Returns the affiliation.sitewwwaddress for the user's affiliation |
| if populated. If not, returns the value for the Global |
| affiliation. If that's not populated, returns vcl.apache.org. |
| |
| =cut |
| |
| sub get_user_affiliation_sitewwwaddress { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| # Try to retrieve the value for the user's affiliation |
| if ($self->request_data->{user}{affiliation}{sitewwwaddress}) { |
| return $self->request_data->{user}{affiliation}{sitewwwaddress}; |
| } |
| |
| # Try to retrieve the value for the Global affiliation |
| my $affiliation_info = get_affiliation_info('Global'); |
| if ($affiliation_info && $affiliation_info->{sitewwwaddress}) { |
| return $affiliation_info->{sitewwwaddress}; |
| } |
| |
| return 'vcl.apache.org'; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_user_affiliation_helpaddress |
| |
| Parameters : none |
| Returns : string |
| Description : Returns the affiliation.helpaddress for the user's affiliation |
| if populated. If not, returns the value for the Global |
| affiliation. If that's not populated, returns |
| 'help@vcl.example.edu'. |
| |
| =cut |
| |
| sub get_user_affiliation_helpaddress { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| # Try to retrieve the value for the user's affiliation |
| if ($self->request_data->{user}{affiliation}{helpaddress}) { |
| return $self->request_data->{user}{affiliation}{helpaddress}; |
| } |
| |
| # Try to retrieve the value for the Global affiliation |
| my $affiliation_info = get_affiliation_info('Global'); |
| if ($affiliation_info && $affiliation_info->{helpaddress}) { |
| return $affiliation_info->{helpaddress}; |
| } |
| |
| return 'help@vcl.example.edu'; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 is_cluster_request |
| |
| Parameters : none |
| Returns : boolean |
| Description : Determines if the current request is a cluster request. |
| |
| =cut |
| |
| sub is_cluster_request { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| my $reservation_count = $self->get_request_reservation_count(0) || 0; |
| if ($reservation_count > 1) { |
| return 1; |
| } |
| else { |
| return 0; |
| } |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_other_cluster_computer_public_ip_addresses |
| |
| Parameters : none |
| Returns : array |
| Description : Retrieves the public IP addresses of all other computers assigned |
| to a cluster request. Returns an empty array if this is not a |
| cluster request. |
| |
| =cut |
| |
| sub get_other_cluster_computer_public_ip_addresses { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| # Make sure this is a cluster request |
| if (!$self->is_cluster_request()) { |
| notify($ERRORS{'WARNING'}, 0, "unable to retrieve cluster computer public IP addresses, this is not a cluster request"); |
| return (); |
| } |
| |
| my $current_reservation_id = $self->reservation_id; |
| my $current_computer_public_ip_address = $self->get_computer_public_ip_address(); |
| my @reservation_ids = $self->get_reservation_ids(); |
| |
| my @cluster_computer_public_ip_addresses; |
| for my $cluster_reservation_id (@reservation_ids) { |
| next if $cluster_reservation_id eq $current_reservation_id; |
| |
| # Get a DataStructure object for each reservation |
| my $reservation_data = $self->get_reservation_data($cluster_reservation_id); |
| if (!$reservation_data) { |
| notify($ERRORS{'WARNING'}, 0, "failed to retrieve cluster computer public IP addresses, data could not be retrieved for reservation $cluster_reservation_id"); |
| next; |
| } |
| |
| # Get the public IP address |
| my $cluster_computer_public_ip_address = $reservation_data->get_computer_public_ip_address(); |
| if (!$cluster_computer_public_ip_address) { |
| notify($ERRORS{'WARNING'}, 0, "failed to retrieve cluster computer public IP address for computer assigned to reservation $cluster_reservation_id"); |
| return; |
| } |
| elsif ($cluster_computer_public_ip_address eq $current_computer_public_ip_address) { |
| notify($ERRORS{'WARNING'}, 0, "computer assigned to reservation $cluster_reservation_id has the same public IP address as the computer assigned to this reservation: $current_computer_public_ip_address"); |
| next; |
| } |
| |
| push @cluster_computer_public_ip_addresses, $cluster_computer_public_ip_address; |
| } |
| |
| notify($ERRORS{'DEBUG'}, 0, "retrieves public IP addresses of other reservations assigned to this cluster request:\n" . join("\n", @cluster_computer_public_ip_addresses)); |
| return sort @cluster_computer_public_ip_addresses; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 substitute_string_variables |
| |
| Parameters : $input_string, $variable_identifier_regex (optional) |
| Returns : $string |
| Description : Replaces sections of the input string matching |
| $variable_identifier_regex with values from the DataStructure |
| object. The default pattern used to locate sections to replace |
| is: |
| \[[^\]]*\]' |
| |
| Meaning, all patterns to replace are enclosed in square brackets. |
| The text within the brackets must exactly match one of the keys |
| of the %SUBROUTINE_MAPPINGS hash defined above. The text must |
| begin and end with lowercase letters and contains any number of |
| lowercase letters and underscores in between. |
| |
| Example: |
| This is input text for user [user_login_id]'s reservation with |
| request/reservation IDs of [request_id]/[reservation_id]. |
| |
| Each section within square brackets gets prepended with 'get_' |
| and the resulting string is executed against this DataStructure |
| object: |
| [user_login_id] --> $self->get_user_login_id(0); |
| |
| The value returned is substituted in the input text: |
| This is input text for user jdoe23's reservation with |
| request/reservation IDs of 3118/3265. |
| |
| =cut |
| |
| sub substitute_string_variables { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| my ($input_string, $variable_identifier_regex) = @_; |
| if (!defined($input_string)) { |
| notify($ERRORS{'WARNING'}, 0, "input string argument was not supplied"); |
| return; |
| } |
| if (!$variable_identifier_regex) { |
| $variable_identifier_regex = '\[[^\]]*\]'; |
| } |
| |
| my $output_string = $input_string; |
| |
| # Extract all sections of input string which should be replaced |
| my @input_substitute_sections = $input_string =~ /($variable_identifier_regex)/g; |
| if (!@input_substitute_sections) { |
| notify($ERRORS{'DEBUG'}, 0, "input string does not contain any sections to replace matching the substitution identifier pattern: '$variable_identifier_regex', returning original input string: '$input_string'"); |
| return $input_string; |
| } |
| #notify($ERRORS{'DEBUG'}, 0, "found sections of input string that match the substitution identifier pattern '$variable_identifier_regex', input string:\n$input_string\n\nmatching sections:\n" . join("\n", @input_substitute_sections)); |
| |
| for my $input_substitute_section (remove_array_duplicates(@input_substitute_sections)) { |
| # Remove brackets, etc from matching section: '[user_login_id]' --> 'user_login_id' |
| my ($subroutine_mapping_key) = $input_substitute_section =~ /\[(.*)\]/; |
| if (!defined($subroutine_mapping_key)) { |
| notify($ERRORS{'CRITICAL'}, 0, "failed to extract subroutine mapping key from section of input string matching substitution identifier pattern '$variable_identifier_regex': '$input_substitute_section'"); |
| next; |
| } |
| #notify($ERRORS{'DEBUG'}, 0, "extracted subroutine mapping key from section of input string: '$input_substitute_section' --> '$subroutine_mapping_key'"); |
| # skip keys derived from [if ...] and [endif] to prevent creation of mappings from HTML comment conditionals |
| next if ($subroutine_mapping_key =~ /^if / || $subroutine_mapping_key eq "endif"); |
| |
| # Attempt to retrieve the substitution value from the DataStructure data |
| # Check if DataStructure.pm implements a matching 'get_' function |
| my $function_name = "get_$subroutine_mapping_key"; |
| if (!$self->can($function_name)) { |
| # Check if implemented without 'get_' |
| # This allows explicit subroutines such as is_server_request to be substituted |
| if ($self->can($subroutine_mapping_key)) { |
| $function_name = $subroutine_mapping_key; |
| } |
| else { |
| notify($ERRORS{'CRITICAL'}, 0, "failed to determine replacement value for substitution section: '$input_substitute_section', DataStructure does not implement a '$function_name' function"); |
| next; |
| } |
| } |
| |
| # Assemble a code string to retrieve the value from the DataStructure: |
| my $eval_code = "\$self->$function_name(0)"; |
| |
| # Evaluate the code string: |
| my $substitution_value = eval $eval_code; |
| if (!defined($substitution_value)) { |
| notify($ERRORS{'CRITICAL'}, 0, "failed to determine replacement value for substitution section: '$input_substitute_section', $eval_code returned undefined"); |
| next; |
| } |
| notify($ERRORS{'DEBUG'}, 0, "determined replacement value for substitution section: '$input_substitute_section', $eval_code = '$substitution_value'"); |
| |
| # Replace substitution section with the retrieved value |
| my $output_string_before = $output_string; |
| # Need to escape brackets or else pattern won't match |
| my $input_substitute_section_escaped = quotemeta($input_substitute_section); |
| $output_string =~ s/$input_substitute_section_escaped/$substitution_value/g; |
| |
| # Make sure the substitution worked |
| if ($output_string_before eq $output_string) { |
| notify($ERRORS{'CRITICAL'}, 0, "failed to replace sections of input string: '$input_substitute_section' (escaped: '$input_substitute_section_escaped') --> '$substitution_value', input string did not change:\n$output_string"); |
| } |
| else { |
| #notify($ERRORS{'DEBUG'}, 0, "replaced sections of input string: '$input_substitute_section' --> '$substitution_value'\nbefore:\n$output_string_before\nafter:\n$output_string"); |
| } |
| } |
| |
| notify($ERRORS{'OK'}, 0, "replaced all matching sections of input string with values retrieved from this DataStructure object:\ninput string: '$input_string'\noutput string: '$output_string'"); |
| return $output_string; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_invalid_substitution_identifiers |
| |
| Parameters : $input_string, $variable_identifier_regex (optional) |
| Returns : array |
| Description : Checks the input string for invalid substitution identifiers. A |
| substitution identifier is valid if it corresponds to one of the |
| keys defined in %SUBROUTINE_MAPPINGS or matches one of the |
| subroutines explicitly defined in DataStructure.pm. Examples: |
| * [user_id] |
| * [computer_short_name] |
| * [is_parent_reservation] |
| |
| An identifier is invalid if it contains a typo or doesn't match |
| any keys or subroutine names: |
| * [usr_id] |
| * [foo_bar] |
| |
| If any invalid subroutines are found, an array is returned |
| containing the strings found in the input string which appear to |
| be intended as substitution identifiers but don't correlate: |
| ('[usr_id]', '[foo_bar]') |
| |
| Note: This subroutine does not need to be called as an object |
| method via $self->data. It's intended to be called from utils.pm. |
| =cut |
| |
| sub get_invalid_substitution_identifiers { |
| my $input_string = shift; |
| if (ref($input_string)) { |
| $input_string = shift; |
| } |
| if (!defined($input_string)) { |
| notify($ERRORS{'WARNING'}, 0, "input string argument was not supplied"); |
| return; |
| } |
| elsif (ref($input_string)) { |
| notify($ERRORS{'WARNING'}, 0, "input string argument is a reference:\n" . format_data($input_string)); |
| return; |
| } |
| |
| my $variable_identifier_regex = shift; |
| if (!$variable_identifier_regex) { |
| $variable_identifier_regex = '\[[^\]]*\]'; |
| } |
| |
| my @invalid_string_variable_identifiers; |
| |
| my @input_string_variable_identifiers = $input_string =~ /($variable_identifier_regex)/g; |
| for my $input_string_variable_identifier (remove_array_duplicates(@input_string_variable_identifiers)) { |
| my ($subroutine_mapping_key) = $input_string_variable_identifier =~ /\[(.*)\]/; |
| if ($subroutine_mapping_key && defined($SUBROUTINE_MAPPINGS{$subroutine_mapping_key})) { |
| next; |
| } |
| elsif (exists(&$subroutine_mapping_key)) { |
| notify($ERRORS{'DEBUG'}, 0, "explicit subroutine exists in DataStructure.pm: $subroutine_mapping_key"); |
| next; |
| } |
| |
| my $get_subroutine_mapping_key = 'get_' . $subroutine_mapping_key; |
| if (exists(&$get_subroutine_mapping_key)) { |
| notify($ERRORS{'DEBUG'}, 0, "explicit subroutine exists in DataStructure.pm: $get_subroutine_mapping_key"); |
| next; |
| } |
| else { |
| notify($ERRORS{'OK'}, 0, "neither mapping key not explicit subroutine exists in DataStructure.pm: $subroutine_mapping_key"); |
| push @invalid_string_variable_identifiers, $input_string_variable_identifier; |
| } |
| } |
| |
| if (@invalid_string_variable_identifiers) { |
| notify($ERRORS{'OK'}, 0, "input string contains invalid substitution identifiers: " . join(', ', @invalid_string_variable_identifiers)); |
| } |
| return @invalid_string_variable_identifiers; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_image_domain_password |
| |
| Parameters : none |
| Returns : string |
| Description : Returns the decrypted Active Directory domain password. |
| |
| =cut |
| |
| sub get_image_domain_password { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| my $reservation_id = $self->reservation_id(); |
| |
| my $secret_id = $self->get_image_domain_secret_id(); |
| if (!defined($secret_id)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to retrieve decrypted domain password, addomain.secretid is not defined in this DataStructure.pm object"); |
| return; |
| } |
| |
| my $encrypted_password = $self->request_data->{reservation}{$reservation_id}{image}{imagedomain}{password}; |
| if (!defined($encrypted_password)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to retrieve decrypted domain password, imagedomain.password is not defined in this DataStructure.pm object"); |
| return; |
| } |
| |
| my $image_domain_password = $self->mn_os->decrypt_cryptsecret($secret_id, $encrypted_password); |
| #notify($ERRORS{'DEBUG'}, 0, "retrieved Active Directory domain password: '$image_domain_password'"); |
| return $image_domain_password; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_domain_credentials |
| |
| Parameters : $imagedomain_id (optional) |
| Returns : array ($username, $domain_password) |
| Description : Attempts to determine and decrypt the username and password for |
| the domain specified by the argument. |
| |
| =cut |
| |
| sub get_domain_credentials { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| my $reservation_id = $self->reservation_id(); |
| my $management_node_id = $self->get_management_node_id(); |
| |
| my $imagedomain_id = shift || $self->request_data->{reservation}{$reservation_id}{computer}{currentimage}{imagedomain}{id}; |
| |
| my ($domain_dns_name, $username, $secret_id, $encrypted_password) = get_management_node_ad_domain_credentials($management_node_id, $imagedomain_id); |
| return unless $domain_dns_name && $username && $secret_id && $encrypted_password; |
| |
| my $decrypted_password = $self->mn_os->decrypt_cryptsecret($secret_id, $encrypted_password) || return; |
| my $decrypted_password_length = length($decrypted_password); |
| my $decrypted_password_hidden = '*' x $decrypted_password_length; |
| notify($ERRORS{'DEBUG'}, 0, "retrieved credentials for Active Directory domain:\n" . |
| "domain ID: $imagedomain_id:\n" . |
| "domain DNS name: $domain_dns_name:\n" . |
| "domain username: $username:\n" . |
| "domain password: $decrypted_password_hidden ($decrypted_password_length characters)" |
| ); |
| return ($domain_dns_name, $username, $decrypted_password); |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| =head2 get_vmhost_profile_password |
| |
| Parameters : $display_warnings (optional) |
| Returns : string |
| Description : Returns the decrypted VM host profile password if both |
| vmprofile.password and vmprofile.secretid are set. If |
| vmprofile.password is set but vmprofile.secretid is not, assumes |
| the password was set prior to VCL 2.5 and returns raw value of |
| vmprofile.password. |
| |
| =cut |
| |
| sub get_vmhost_profile_password { |
| my $self = shift; |
| if (ref($self) !~ /VCL::/i) { |
| notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method"); |
| return 0; |
| } |
| |
| my $display_warnings = shift; |
| $display_warnings = 1 unless defined($display_warnings); |
| |
| my $reservation_id = $self->reservation_id(); |
| |
| my $password = $self->request_data->{reservation}{$reservation_id}{computer}{vmhost}{vmprofile}{password}; |
| if (!defined($password)) { |
| notify($ERRORS{'WARNING'}, 0, "failed to retrieve decrypted VM profile password, vmprofile.password is not defined in this DataStructure.pm object") if $display_warnings; |
| return; |
| } |
| |
| my $secret_id = $self->get_vmhost_profile_secret_id(0); |
| if (!defined($secret_id)) { |
| notify($ERRORS{'DEBUG'}, 0, "vmprofile.password is set but vmprofile.secretid is NOT, assuming vmprofile.password is a pre-VCL 2.5 clear-text password: '$password'"); |
| return $password; |
| } |
| |
| my $decrypted_password = $self->mn_os->decrypt_cryptsecret($secret_id, $password) || return; |
| my $decrypted_password_length = length($decrypted_password); |
| my $decrypted_password_hidden = '*' x $decrypted_password_length; |
| notify($ERRORS{'DEBUG'}, 0, "decrypted VM host profile password: '$decrypted_password_hidden' ($decrypted_password_length characters)"); |
| return $decrypted_password; |
| } |
| |
| #////////////////////////////////////////////////////////////////////////////// |
| |
| 1; |
| __END__ |
| |
| =head1 SEE ALSO |
| |
| L<http://cwiki.apache.org/VCL/> |
| |
| =cut |