in managementnode/lib/VCL/Module/Provisioning/VMware/VIM_SSH.pm [3194:3321]
sub _parse_vim_cmd_output {
my $self = shift;
if (ref($self) !~ /VCL::Module/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
my ($argument, $debug) = @_;
if (!defined($argument)) {
notify($ERRORS{'WARNING'}, 0, "vim-cmd output argument was not supplied");
return;
}
my @lines;
if (my $type = ref($argument)) {
if ($type eq 'ARRAY') {
@lines = @$argument;
}
else {
notify($ERRORS{'WARNING'}, 0, "argument is a $type reference, only an ARRAY reference or string are supported");
return;
}
}
elsif (scalar(@_) > 1) {
@lines = @_;
}
else {
@lines = split("\n", $argument);
}
my $statement;
my $numbered_statement;
my $line_number = 0;
for my $line (@lines) {
# Skip blank lines
if ($line !~ /\S/) {
next;
}
# Some commands such as 'vim-cmd vmsvc/get.summary' add this to the beginning:
# Listsummary:
if ($line =~ /:$/) {
notify($ERRORS{'DEBUG'}, 0, "skipping line: $line");
next;
}
$line_number++;
my $original_line = $line;
# Remove trailing newlines
$line =~ s/\n+$//g;
# Remove class names in parenthesis from beginning class name of indented lines
# ' (vim.vm.device.xxx) {' --> ' {'
$line =~ s/^(\s+)\([^\)]*\)\s*/$1/g;
# Remove class names at beginning of a line surrounded by parenthesis
# '(vim.vm.device.VirtualPointingDevice) {' --> 'vim.vm.device.VirtualPointingDevice => {'
$line =~ s/^\(([^\)]+)\)\s*{/$1 => {/gx;
# Remove class names
# '(vim.vm.ConfigOptionDescriptor) ['
$line =~ s/^\([^\)]+\)\s*(\[)/$1/gx;
# Add comma to lines containing a closing curly bracket
# ' }' --> ' },'
$line =~ s/^(\s*)}\s*$/$1},/g;
# Remove class names after an equals sign
# 'backing = (vim.vm.device.VirtualDevice.BackingInfo) null,' --> 'backing = null'
$line =~ s/(=\s+)\([^\)]+\)\s*/$1/g;
# Add comma to lines containing = sign which don't end with a comma
# 'value = xxx' --> 'value = xxx,'
$line =~ s/(=\s+[^,]+[\w>])$/$1,/g;
# Surround values after equals sign in single quotes
# value = xxx, --> value = 'xxx',
# value = "xxx", --> value = 'xxx',
$line =~ s/(=\s+)["']?([^"']+)["']?,/$1'$2',/g;
# Surround values before equals sign in single quotes
$line =~ s/^(\s*)["']?([^\s"']+)["']?(\s*=)/$1'$2'$3/g;
# Change 'null' to undef and add =>
# 'busSlotOption null,' --> 'busSlotOption => undef,'
$line =~ s/(\w\s+)null,/$1 => undef,/g;
# Change = to =>
$line =~ s/=(\s+.+)/=>$1/g;
# Add => before array and hash references
# 'guestOSDescriptor [' --> 'guestOSDescriptor => ['
$line =~ s/(\w\s+)([\[{])/$1=>$2/g;
$statement .= "$line\n";
$numbered_statement .= "$line_number:\n";
$numbered_statement .= "$original_line\n";
$numbered_statement .= "$line\n";
}
# Enclose the entire statement in curly brackets
if ($statement =~ /^[^\n]+{/) {
$statement = "{\n$statement\n}";
}
if ($debug) {
print "\n";
print '.' x 200 . "\n";
print "Statement:\n$statement\n";
print '.' x 200 . "\n";
}
# The statement variable should contain a valid definition
my $result = eval($statement);
if ($EVAL_ERROR) {
notify($ERRORS{'WARNING'}, 0, "failed to parse vim-cmd output, error:\n$EVAL_ERROR\n$numbered_statement");
return;
}
elsif (!defined($result)) {
notify($ERRORS{'WARNING'}, 0, "failed to parse vim-cmd output:\n$numbered_statement");
return;
}
else {
#notify($ERRORS{'DEBUG'}, 0, "parsed vim-cmd output:\n" . format_data($result));
return $result;
}
}