VMware vCLI Perl "who done it" script - perl

I've been trying to do this for a while and I just can't seem to understand the vCLI SDK. I believe the MO that I want to use is
ServiceContent->Task Manager, then print out the recent task. Here is my subroutine for doing it:
sub TaskManager {
my $begin;
my $mor = Vim::get_service_content()->taskManager;
my $taskmanager_view = Vim::get_view(mo_ref => $mor);
my $my_filterSpec = TaskFilterSpec->new();
my $eventArray = $taskmanager_view->CreateCollectorForTasks(filter => $my_filterSpec);
foreach (#$eventArray) {
# my $collector_view = Vim::get_view(mo_ref => $eventArray);
print $_->recentTask . "\n";
}
}
When I run this I either get:
Not an ARRAY reference at ./TaskManager.pl line 43.
When I change this, I then get:
subroutine &ManagedObjectReference::recentTask called at ./TaskManager.pl line 45
Here's one of the DOCS I've been looking at
https://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.TaskManager.html
I also have some conversations happening here:
https://www.reddit.com/r/vmware/comments/4qfaql/help_with_vcli_perl_script/
EDIT: I changed my subroutine to the following:
sub TaskManager {
my $begin;
my $mor = Vim::get_service_content()->taskManager;
my $taskmanager_view = Vim::get_view(mo_ref => $mor);
my $my_filterSpec = TaskFilterSpec->new();
my $eventArray = $taskmanager_view->CreateCollectorForTasks(filter => $my_filterSpec);
foreach ($eventArray) {
my $newRecentTask = $taskmanager_view->description;
print $newRecentTask . "\n";
}
}
But the problem is that the print statement is returning a hash value, not something I can use. Any ideas how to get something readable?

Related

how to increment hash of hash in perl

failing to properly populate a HoH using this code:
when i run the loop using below:
while (my $form = $form_rs->next ()){
my $menu=$form->get_column("fmenu");
my $script=$form->get_column("fscript");
my $name=$form->get_column("ftitle");
$itemList->{$menu} = {
$script => $name
};
}
print Dumper $itemList;
it runs correctly but since $menu is repeating it only keeps last value in the HoH. So i get erroneous output in Data Dumper. I get only 1 record for each 'menu', whereas there should be many.
getting:
itemList=>{
menu1=>{
script1=>formName1
},
menu2=>{
script3=>formName3
}
...(and so on)
}
whereas EXPECTED:
itemList=>{
menu1=>{
script1=>formName1,
script2=>formName2
},
menu2=>{
script3=>formName3,
...(and so on)
}
...(and so on)
}
pl help.
thank you.
Then you want to update $itemList->{$menu}{$script} rather than assign a reference to a one-element hash to $itemList->{$menu}.
$itemList->{$menu}{$script} = $name;

Perl using Win32::PerfLib

I'm trying to understand Win32::PerfLib better, and I mustn't use Win32::PerfMon.
Two example I have questions about:
First example, is the classic from CPAN:
use Win32::PerfLib;
my $server = "";`enter code here`
Win32::PerfLib::GetCounterNames($server, \%counter);
%r_counter = map { $counter{$_} => $_ } keys %counter;
# retrieve the id for process object
$process_obj = $r_counter{Process};
# retrieve the id for the process ID counter
$process_id = $r_counter{'ID Process'};
# create connection to $server
$perflib = new Win32::PerfLib($server);
$proc_ref = {};
# get the performance data for the process object
$perflib->GetObjectList($process_obj, $proc_ref);
$perflib->Close();
$instance_ref = $proc_ref->{Objects}->{$process_obj}->{Instances};
foreach $p (sort keys %{$instance_ref})
{
$counter_ref = $instance_ref->{$p}->{Counters};
foreach $i (keys %{$counter_ref})
{
if($counter_ref->{$i}->{CounterNameTitleIndex} == $process_id)
{
printf( "% 6d %s\n", $counter_ref->{$i}->{Counter},
$instance_ref->{$p}->{Name}
);
}
}
}
Could someone explain in depth the 4th line?
I didn't understand why we use $_ for and
what it represents, although I read about it
but in this case I don't know. In addition
what's the $counter{$_} => $_ meaning?
Second question is from this code, which gets the cpu %
from perfmon:
use Win32::PerfLib;
($server) = #ARGV;
# only needed for PrintHash subroutine
#Win32::PerfLib::GetCounterNames($server, \%counter);
$processor = 238;
$proctime = 6;
$perflib = new Win32::PerfLib($server);
$proc_ref0 = {};
$proc_ref1 = {};
$perflib->GetObjectList($processor, $proc_ref0);
sleep 5;
$perflib->GetObjectList($processor, $proc_ref1);
$perflib->Close();
$instance_ref0 = $proc_ref0->{Objects}->{$processor}->{Instances};
$instance_ref1 = $proc_ref1->{Objects}->{$processor}->{Instances};
foreach $p (keys %{$instance_ref0})
{
$counter_ref0 = $instance_ref0->{$p}->{Counters};
$counter_ref1 = $instance_ref1->{$p}->{Counters};
foreach $i (keys %{$counter_ref0})
{
next if $instance_ref0->{$p}->{Name} eq "_Total";
if($counter_ref0->{$i}->{CounterNameTitleIndex} == $proctime)
{
$Numerator0 = $counter_ref0->{$i}->{Counter};
$Denominator0 = $proc_ref0->{PerfTime100nSec};
$Numerator1 = $counter_ref1->{$i}->{Counter};
$Denominator1 = $proc_ref1->{PerfTime100nSec};
$proc_time{$p} = (1- (($Numerator1 - $Numerator0) /
($Denominator1 - $Denominator0 ))) * 100;
printf "Instance $p: %.2f\%\n", $proc_time{$p};
}
}
}
Why does the programmer had to use the method "GetObjectList"
Two times and put the sleep method between them?
And why we can't just take the cpu percent like perfmon shows
and we have to make all those calculations?
Thanks in advance,
Fam Pam.
In this code:
Win32::PerfLib::GetCounterNames($server, \%counter);
%r_counter = map { $counter{$_} => $_ } keys %counter;
You are stroing the perfdata in %counter hash. The map in this case creates a reverse hash where the earlier values becomes keys.
Example:
from apple => 'fruit' to fruit => 'apple

Perl win32::GUI progressbar

Progress bar is not following the script. I want to display progressbar as the script executes. when it done it should stop. currently it is displying full process then going for printing output.
Please find my code below:
$Progress_bars = $main->AddProgressBar(
-pos => [10,840],
-background => [0,255,85],
-smooth => 1,
-size => [470,20],
);
my $intended_max = 100;
my $x = 11;
my $y = int($intended_max/$x);
$Progress_bars->SetRange(0,$x*$y);
for (1 .. $x) {
Win32::GUI::DoEvents();
$Progress_bars->SetStep($y);
$Progress_bars->StepIt();
Win32::Sleep(50);
}
$output = $telnet->print('ls');
print $output;
You're code is increasing the value by the progress value rather than setting it directly.
Try calling the SetPos methods instead of SetStep and StepIt.
(Note that I don't use Win32::GUI, so I'm guessing the method name based on MSDN.)

Perl NetSNMP extension with multiple devices

I have got a machine (Debian based) with some temperature sensors attached to it, and i would like to query them over snmp, from one script. I can work with one sensor ok, but i am struggling when i plug another one in.
What I am trying to do is loop through each device, and give each one an id, then use this ID as part of the OID, then give it a value.
I've never worked with snmp before, and my perl is not great so any help would be much appreciated. Below is my code:
#!/usr/bin/perl
use NetSNMP::agent (':all');
use NetSNMP::ASN qw(ASN_OCTET_STR ASN_INTEGER);
$BASE_OID=".1.3.6.1.4.1.41050";
$dev_id=1;
$string_value;
$integer_value;
sub pimon_handler {
my ($handler, $registration_info, $request_info, $requests) = #_;
my $request;
my $oid_key;
for($request = $requests; $request; $request = $request->next()) {
$oid_key=$BASE_OID . '.' . $dev_id;
my $oid = $request->getOID();
if ($request_info->getMode() == MODE_GET) {
if ($oid == new NetSNMP::OID($oid_key . '.0')) {
$request->setValue(ASN_OCTET_STR, $string_value);
}
elsif ($oid == new NetSNMP::OID($oid_key . '.1')) {
$request->setValue(ASN_INTEGER, $integer_value);
}
} elsif ($request_info->getMode() == MODE_GETNEXT) {
if ($oid == new NetSNMP::OID($oid_key . '.0')) {
$request->setOID($oid_key . '.1');
$request->setValue(ASN_INTEGER, $integer_value);
}
elsif ($oid < new NetSNMP::OID($oid_key . '.0')) {
$request->setOID($oid_key . '.0');
$request->setValue(ASN_OCTET_STR, $string_value);
}
}
}
}
#location of where we are going to find the 1wire devices
#sensors = `cat /sys/bus/w1/devices/w1_bus_master1/w1_master_slaves`;
chomp(#sensors);
#loop through the sensors we find
foreach $line(#sensors) {
#work out the temp we have got. Need to change this for other sensor types
$output = `cat /sys/bus/w1/devices/$line/w1_slave`;
$output =~ /t=(?<temp>\d+)/;
$integer_value = sprintf "%.0f",$+{temp} / 1000;
$string_value = $line;
my $agent = new NetSNMP::agent();
$agent->register("Pimon$looptest", $BASE_OID . '.' . $dev_id,
\&pimon_handler);
print "Dev $dev_id temp $line temp is $integer_value\n";
$dev_id ++;
}
Are you getting any errors or output?
I suspect that your problem lies in and around your reading the data file by shelling-out to cat instead of opening the file and looping over the linewise contents.
Try dumping the value of #sensors. if it is a single entry array, with the only element containing your entire file, then simply switch #sensors to be scalar. then split $sensors into an array and loop over that.
my $sensors = `read something`
chomp $sensors;
my #sensors = split(/\n/, $sensors);
foreach $line (#sensors) {
...

Mojolicious wildcard placeholders and question mark

The wildcard placeholder (*) is said to match absolutely everything.
But I'm afraid that it doesn't...
I have a webservice with the following method:
get '/*param' => sub {
my $self = shift;
my $param = $self->stash('param');
$self->app->log->debug($param);
}
When i query my service with: http://localhost:3000/search
then the method logs "search" which is ok
but
when i query my service with: http://localhost:3000/search?page=1
then the method also logs "search" which is not ok IMO
I also tried replacing
get '/*param' => sub {
with
get '/:param' => [param => qr/.*/] => sub {
but the result is the same.
Does anybody know of a way around this?
Or should I file this as a bug?
Regards,
Lorenzo
UPDATE
for people with the same problem, I've worked around this issue like this:
get '/*path' => sub {
my $self = shift;
my $path = $self->stash('path');
my #params = $self->param;
if (scalar #params > 0) {
$path .= '?';
foreach my $param (#params) {
$path .= $param . '=' . $self->param($param) . '&';
}
$path = substr($path, 0, length($path) - 1);
}
$self->app->log->debug($path);
}
?page= its not url.
Its param.
So no any bugs here.
you have 'search' in $param.
And $page=1 in stash.
I think Korjavin is right, that's expected behavior. Looks like "page=1" as a parameter and should be in $stash->param('page'). See GET-POST-parameters in ::Lite
If it does not work, maybe renaming the "param" placeholder to something else helps? Maybe it's a name-clash.
The request parameters wouldn't be in the stash.
They're in
$self->req->params
So
my $params = $self->req->params->to_hash;
$self->app->log->debug(Dumper $params);
Should allow you to see the information you're after