--- /dev/null
+#!/local/perl/5.6.1/bin/perl -wd
+
+=pod
+
+=head1 B<NAME>
+
+UiO::Ip2net - Routines for treatment of network info
+
+=head1 B<SYNOPSIS>
+
+S<< use lib qw(/site/lib/perl); >> E<10>
+S<< use UiO::Ip2net; >>
+
+=head1 B<DESCRIPTION>
+
+Perl package that export network helper functions
+
+=head1 B<INTERNAL>
+
+=over 4
+
+=cut
+
+
+package UiO::Ip2net;
+
+use strict;
+use Net::Netmask;
+use Net::DNS;
+use Socket6;
+use Socket;
+use UiO::Utils;
+
+use vars qw(
+%networks
+%dns
+@ISA
+@EXPORT
+);
+
+my (
+ $VERSION,
+ @axfr,
+ $block,
+ %dns,
+);
+
+
+
+use Exporter();
+@ISA = qw(Exporter);
+
+@EXPORT = qw(
+%networks
+%dns
+parse_networks
+NETMASK
+BROADCAST
+GATEWAY
+DNSRESOLVE
+VLAN
+VLANID
+AXFR
+rIp
+rFqdn
+get_ip
+get_ip_info
+get_dns_axfr
+get_my_vlan
+find_virt_servers
+gethostbyip6
+);
+
+
+$VERSION = 1.01;
+
+
+
+###############################################################
+# Internal functions, not exported
+###############################################################
+
+=item get_a()
+
+Internal Function used by AXFR, to resolve "IN A" entryies
+
+=cut
+sub get_a {
+ foreach my $entry (@axfr) {
+ if ($entry->{'type'} eq 'TXT') {
+ $entry->{'rdata'}=~s/^\cG|^\cF|^\cI|^\cK|\cQ//;
+ $dns{'txt'}->{$entry->{'name'}}=$entry->{'rdata'};
+ }
+ if ($entry->{'type'} eq 'A') {
+ $dns{'fqdn'}->{$entry->{'name'}}=$entry->{'address'};
+ if (defined $dns{'ip'}->{$entry->{'address'}}) {
+ next;
+ }
+ $dns{'ip'}->{$entry->{'address'}}=$entry->{'name'};
+ }
+ }
+}
+
+=item get_cname()
+
+Internal Function used by AXFR, to resolve "IN CNAME" entryies
+
+=cut
+
+sub get_cname {
+ foreach my $entry (@axfr) {
+ if ($entry->{'type'} eq 'CNAME') {
+ if (defined $dns{'fqdn'}->{$entry->{'cname'}} ) {
+ next;
+ }
+ $dns{'fqdn'}->{$entry->{'name'}}=$dns{'ip'}->{$entry->{'cname'}};
+ }
+ }
+}
+
+
+=back
+
+=head1 EXTERNAL
+
+=over 4
+
+=item B<parse_networks($params)>
+
+
+
+Parses the F</local/etc/networks>, to enable other functions to
+resolve netmask, broadcast, gateway, vlan and vlanId for a ip or hostname
+
+Include the following lines in your script to enable the function:
+
+S<<< my %params = ( 'networks' => '/local/etc/networks' ) >>>
+S<my $params=\%params;>
+S<parse_networks($params);>
+
+This function is currenty used by the following functions:
+
+=over 8
+
+=cut
+
+sub parse_networks {
+ my ($params) = @_;
+ open(FH, $$params{'networks'}) || die "Cant open networks file\n";
+
+ while(<FH>) {
+ chomp;
+ if (/^\s*(\d+\.\d+\.\d+\.\d+\/\d+)\s+\#\s+(\w+)/) {
+ s/\#|\(.*\)//g;
+ my @line=split(/\s+/,$_);
+ my $network=shift(@line);
+ my ($vlan, $router);
+ my $vr=shift(@line);
+ if ($vr =~ /:vlan/) {
+ s/,//g;
+ $networks{$network}->{'router'}=$networks{$network}->{'vlanId'}=$vr;
+ $networks{$network}->{'vlanId'}=~s/.*:vlan|\,//g;
+ $networks{$network}->{'router'}=~s/:vlan.*|\/.*//;
+ } else { next }
+ $networks{$network}->{'vlan'}=join(" ",@line);
+
+ }
+ }
+
+ for my $a (keys %networks) {
+ #if ($a eq "network") {
+ #print ;
+ #}
+ $block = new Net::Netmask($a);
+ $block->storeNetblock();
+ }
+ return(0);
+}
+
+###############################################################
+# Subrutines
+###############################################################
+
+=item * B<NETMASK($stat)>
+
+my $stat = findNetblock($ip)E<10> E<8>my $netmask=NETMASK($stat)
+
+Returns the netmask on the following format : 255.255.255.0
+
+=cut
+sub NETMASK {
+ my $lnet = shift;
+ my $lblock = new Net::Netmask($lnet);
+ $lblock->storeNetblock();
+ return($lblock->mask);
+
+}
+
+=item * B<BROADCAST($stat)>
+
+my $stat = findNetblock($ip)E<10> E<8>my $broadcast=BROADCAST($stat)
+
+Returns the broadcast address
+
+=cut
+sub BROADCAST {
+ my $lnet = shift;
+ my $lblock = new Net::Netmask($lnet);
+ $lblock->storeNetblock();
+ return($lblock->broadcast);
+}
+
+=item * B<GATEWAY($stat)>
+
+my $stat = findNetblock($ip)E<10> E<8>my $gateway=GATEWAY($stat)
+
+Returns what should be the default gateway for the specified ip
+
+=cut
+sub GATEWAY {
+ my $lnet = shift;
+ my $lblock = new Net::Netmask($lnet);
+ $lblock->storeNetblock();
+ return($lblock->nth(1));
+}
+=item * B<VLANID($stat)>
+
+my $stat = findNetblock($ip)E<10> E<8>my $vlanid=VLANID($stat)
+
+Returns vlanid for the specified ip
+
+=cut
+sub VLANID {
+ my $lookup = shift;
+ return $networks{$lookup}->{'vlanId'};
+}
+=item * B<VLAN($stat)>
+
+my $stat = findNetblock($ip)E<10> E<8>my $vlanid=VLAN($stat)
+
+Returns vlan number for the specified ip
+
+=cut
+sub VLAN {
+ my $lookup = shift;
+ return $networks{$lookup}->{'vlan'};
+}
+
+
+=back
+
+=item B<get_dns_axfr()>
+
+my %dns=get_dns_axfr
+
+Helper function for the fuction I<AXFR>. Initialices two arrays and passes them to
+AXFR. The first hash is a list over domains to resolve, and the other is a list over
+dns servers.
+
+The fuctions returns a hash, %dns, which is a zone transfer for all domains specified.
+When resolving 100+ servers, you may find this function much faster than doing individual
+lookups for each server.
+
+You may address the hash directly, or use the helper functions :
+
+=over 8
+
+=cut
+sub get_dns_axfr {
+}
+
+
+
+=item * B<rIp('hostname.nsc.no')>
+
+Compares the input with the %dns hash. If it finds a match, returns IP.
+
+=cut
+sub rIp {
+ my $fqdn=shift;
+ if ($fqdn =~/^\d+\.\d+\.\d+\.\d+$/) {
+ return $fqdn;
+ } else {
+ if (!$dns{'fqdn'}->{$fqdn}) {
+ return 1;
+ }
+ return $dns{'fqdn'}->{$fqdn};
+ }
+}
+
+=item * B<rFqdn('10.10.10.10')>
+
+Compares the input with the %dns hash. If it finds a match, returns FQDN.
+
+=cut
+sub rFqdn {
+ my $ip=shift;
+ if ($ip !~/^\d+\.\d+\.\d+\.\d+$/) {
+ return $ip;
+ } else {
+ if (!$dns{'ip'}->{$ip}) {
+ return;
+ }
+ return $dns{'ip'}->{$ip};
+ }
+}
+
+# #####################################################################
+# Old fasion resolve ip from DNS
+# #####################################################################
+
+=back
+
+=item B<get_ip('hostname.nsc.no')>
+
+Resolve ip using gethostbyname. Used for hosts where a zone transfer does not
+work.
+
+=cut
+sub get_ip {
+ my ($hostname) = @_;
+ #&debug("resolve $hostname");
+ my $ip;
+ my $packed_ip = gethostbyname($hostname);
+ if (defined $packed_ip) {
+ $ip = inet_ntoa($packed_ip);
+ return ($ip);
+ } else {
+ return 1;
+ }
+}
+
+# #####################################################################
+# Find detailed info about your host
+# #####################################################################
+
+=item B<get_ip_info('hostname.nsc.no', $IFNAME, %inter)>
+
+Harvest ip, vlan etc information for the current host/interface and return
+interface name and a hash (%inter).
+
+See the module L<UiO::Vmware> for a reference
+
+=cut
+sub get_ip_info {
+ my ($host, $IFNAME, %inter) = @_;
+
+ if ($host eq "localhost" or $host eq "127.0.0.1") {
+ return (1, %inter);
+ }
+
+
+ my ($interface, $intername, $virtual, $vlanId, $lanid) ;
+ my ($vlan, $netmask, $broadcast, $gateway);
+
+ if ($IFNAME ne "vmware") {
+ ($interface, $intername, $virtual, $vlanId, $lanid) = get_my_vlan( $IFNAME );
+ }
+
+
+ my $ip=rIp($host);
+ if ($ip eq "1") {
+ $ip=&get_ip($host);
+ if ($ip eq "1") {
+ push (@{$inter{$interface}->{'virtual'}}, {
+ 'hostname' => $host,
+ });
+ return ($interface, %inter);
+ }
+ }
+ my $hostname=rFqdn($ip);
+ if ($hostname eq "1") {
+ undef $hostname;
+ }
+ my $stat = findNetblock($ip);
+ if ($stat) {
+ $vlanId=VLANID($stat);
+ $vlan=VLAN($stat);
+ $netmask=NETMASK($stat);
+ $broadcast=BROADCAST($stat);
+ $gateway=GATEWAY($stat);
+ }
+ my %net;
+ $net{'ip'}=$ip if defined $ip;
+ $net{'hostname'}=$hostname if defined $hostname;
+ #$net{'vlanId'}=$vlanId if defined $vlanId;
+ #$net{'vlan'}=$vlan if defined $vlan;
+ $net{'netmask'}=$netmask if defined $netmask;
+ $net{'broadcast'}=$broadcast if defined $broadcast;
+ $net{'gateway'}=$gateway if defined $gateway;
+
+ $inter{$interface}->{'label'}=$IFNAME;
+ $inter{$interface}->{'gateway'}=$gateway;
+ $inter{$interface}->{'netmask'}=$netmask;
+ $inter{$interface}->{'vlan'}=$vlan;
+ $inter{$interface}->{'vlanId'}=$vlanId;
+
+ push (@{$inter{$interface}->{'virtual'}}, {
+ %net,
+ });
+ return ($interface, %inter);
+}
+
+
+# #####################################################################
+# Find my VLAN, parsing the interface name
+# #####################################################################
+=item B<get_my_vlan($interface_name)>
+
+Tries to figure out the vlan number for a given interface name.
+Exsample ; if interface name is bge222000, the function will
+return 222.
+
+See the function L<UiO::Ip2net::get_ip_info> for a reference
+
+=cut
+sub get_my_vlan {
+ my ($inter) = @_;
+ my ( $interface, $virtual, $xx ) =split(/:/,$inter);
+
+ if (not defined $virtual) {
+ $virtual=0;
+ }
+
+ my $lanid=$interface;
+ my $intername=$interface;
+
+ $lanid=~s/^\D.*\D//g;
+ $intername=~s/\d*$//g;
+ my $vlanId=0;
+ if (length($lanid) > 3) {
+ # we have some vlans
+ $vlanId=$interface;
+ $vlanId=~s/^\D.*\D|\d\d\d$//g;
+ $lanid=int(substr($lanid, -3));
+ }
+ return ($interface, $intername, $virtual, $vlanId, $lanid);
+}
+
+=item B<AXFR($nameservers, $domains)>
+
+my %dns=AXFR(\@nameservers, \@domains);
+
+Returns a hash (%dns), whith a full zonetransfer for the domains specified in the second parameter.
+
+=cut
+sub AXFR {
+ my ($nameservers, $domains) = @_;
+ my $res = Net::DNS::Resolver->new(nameservers => [ @$nameservers ], recurse=> 1,debug => 0,searchlist =>[ @$domains ]);
+ $res->tcp_timeout(10);
+ foreach my $domain (@$domains) {
+ push (@axfr, $res->axfr($domain));
+ }
+ &get_a;
+ &get_cname;
+ return (%dns);
+}
+=item * B<DNSRESOLVE($stat)>
+
+Must check if this function is in use
+
+=cut
+sub DNSRESOLVE {
+ my $lookup = shift;
+ my $res = Net::DNS::Resolver->new;
+ my $query = $res->search($lookup);
+ if ($query) {
+ foreach my $rr ($query->answer) {
+ next unless $rr->type eq "A";
+ return ($rr->address);
+ }
+ } else {
+ return(1);
+ }
+}
+
+sub gethostbyip6 {
+ my ($nets) = @_;
+
+ my ($family, $socktype, $proto, $saddr, $canonname, @res);
+ @res = getaddrinfo($nets, 'daytime', AF_UNSPEC, SOCK_STREAM);
+ while (scalar(@res) >= 5) { ($family, $socktype, $proto, $saddr, $canonname, @res) = @res;}
+ my $resName;
+ $resName=gethostbyaddr(inet_aton($nets),AF_INET) if ($family == 2);
+ $resName=gethostbyaddr(inet_pton($family, $nets),AF_INET6) if ($family != 2);
+
+ return $resName;
+}
+
+sub find_virt_servers {
+}
+
+# ldap ting
+#
+# ldapsearch -x -h ldap -b 'cn=system,dc=uio,dc=no' -s sub '(objectclass=ipNetwork)'|less
+
+1;
+
+=back
+
+=head1 SEE ALSO
+
+L<UiO::XML> L<UiO::Utils> L<UiO::Param>
+
+=head1 AUTHOR
+
+Created by Ragnar Hongset @ RagHon Consulting
+
+=cut
--- /dev/null
+#!/local/perl/5.6.1/bin/perl -wd
+my $nr=0;
+
+# $Source: /local/perl/lib/UiO/RCS/Vmware.pm,v $
+# $Id: Vmware.pm,v 1.9 2010/10/23 10:46:25 root Exp $
+
+=pod
+
+=head1 B<NAME>
+
+UiO::Vmware - Routines for extracting information from Vmware
+
+=head1 B<SYNOPSIS>
+
+S<< use lib qw(/site/lib/perl); >> E<10>
+S<< use UiO::Vmware; >>
+
+=head1 B<DESCRIPTION>
+
+Perl package that connect to Vmware Control Center Servers, and extracts data
+into a hash named %all_servers. This hash is later used to create XML outout
+for SAM
+
+The following scripts are using this package, and can be used as examples
+of how these functions can be used:
+
+
+=over 4
+
+=item B<esxHarvest.pl(1)>
+
+
+=back
+
+=head1 B<INTERNAL>
+
+=over 4
+
+=cut
+
+
+
+package UiO::Vmware;
+
+use strict;
+use diagnostics;
+use Net::Netmask;
+use Net::DNS;
+#use IO::Socket::INET6;
+use Socket;
+use VMware::VIRuntime;
+use VMware::VILib;
+use Sub::Override;
+use UiO::Utils;
+use UiO::Ip2net;
+use UiO::DB;
+use utf8;
+binmode STDIN, ':utf8';
+binmode STDOUT, ':utf8';
+
+use vars qw(
+ @ISA
+ @EXPORT
+ );
+
+my (
+ $VERSION,
+ );
+
+
+
+use Exporter();
+@ISA = qw(Exporter);
+
+@EXPORT = qw(
+ get_vmware_info
+ get_search_filter_spec2
+ get_virt_server
+ );
+
+
+$VERSION = 1.01;
+
+
+# #####################################################################
+# Get details for each vm
+# #####################################################################
+
+=item vmware_guest($vm, $host, $cluster, $datacenter, $all_servers)
+
+Utilices the Vmware Perl SDK, to populate %all_servers with info about vmware
+virtual hosts
+
+=back
+
+=cut
+sub vmware_guest {
+ my ( $vm, $host, $cluster, $datacenter, $all_servers ) = @_;
+
+ my $vm_hostname;
+
+ if ($vm->runtime->powerState->val ne "poweredOff" and $vm->config->template != 1) {
+
+ $vm_hostname=$vm->{'name'} if (exists $vm->{'name'});
+ if (exists $vm->{'guest'}) {
+ $vm_hostname=$vm->guest->{'hostName'} if (exists $vm->guest->{'hostName'} and $vm->guest->{'hostName'} !~ /[a-zA-Z]/)
+ } else {
+ print "VM NAME = $vm_hostname \n";
+ }
+ } else {
+ &debug("No hostname defined for guest, returning");
+ return $all_servers;
+ }
+ my %opthash = (
+ 'pri' => 100,
+ 'serverIN_UNIT' => $cluster->name ,
+ 'description' => $vm->config->annotation,
+ 'sockets' => $vm->config->hardware->numCPU,
+ 'serverCPUSPEED' => $vm->summary->quickStats->distributedCpuEntitlement,
+ 'serverMEMORY' => $vm->config->hardware->memoryMB,
+ 'vmwareTOOLSSTATUS' => $vm->guest->toolsStatus->val,
+ 'vmwareTOOLSVERSION' => $vm->guest->toolsVersion,
+ 'eq_type' => 'Virtual server',
+ 'serverMODEL' => 'VMware',
+ 'serverOS' => $vm->config->guestFullName );
+
+
+ if (defined $vm->availableField) {
+ foreach my $custf (@{$vm->availableField}) {
+ $opthash{'availableField'}->{$custf->key}=$custf->name;
+ }
+ }
+ if (defined $vm->customValue) {
+ foreach (@{$vm->customValue}) {
+ $opthash{'SelfservicedBy'}=$_->value if (defined $opthash{'availableField'}->{$_->key} and $opthash{'availableField'}->{$_->key} eq "SelfservicedBy");
+ $opthash{'group_owner'}=$_->value if (defined $opthash{'availableField'}->{$_->key} and $opthash{'availableField'}->{$_->key} eq "CustomSamGroup");
+ }
+ }
+
+ if (!defined $opthash{'group_owner'}) {
+ if ($opthash{'serverOS'}=~/Microsoft/) {
+ # if ($vm->guest->hostName=~/2000ad.no$|link.no$|op.nsc.no$|tmn.telenor.no$|wowqa.telenor.local$/) {
+ if ($vm_hostname=~/2000ad.no$|link.no$|op.nsc.no$|tmn.telenor.no$|wowqa.telenor.local$/) {
+ $opthash{'group_owner'}="Windows";
+ }
+ } elsif ($opthash{'serverOS'}=~/VMware/) {
+ #$opthash{'group_owner'}="Windows";
+ } else {
+ #$opthash{'group_owner'}="Unix";
+ }
+ }
+
+
+ # get NFS disk info
+ foreach my $fs (@{$vm->config->datastoreUrl}) {
+ foreach my $hfs (@{$host->config->fileSystemVolume->mountInfo}) {
+ if ($hfs->volume->name eq $fs->name) {
+ my $remoteHost="";
+ my $remotePath="";
+ if (defined $hfs->volume->{remoteHost}) {
+ $remoteHost=$hfs->volume->remoteHost;
+ }
+ if (defined $hfs->volume->{remotePath}) {
+ $remotePath=$hfs->volume->remotePath;
+ }
+ push (@{$opthash{'fs'}}, {
+ 'name' => $fs->name,
+ 'url' => $fs->url,
+ 'filer' => $remoteHost,
+ 'filer_path' => $remotePath,
+ });
+
+ }
+ }
+ }
+ if ( defined $vm->guest->{disk} ) {
+ foreach my $osfs (@{$vm->guest->disk}) {
+ push (@{$opthash{'osfs'}}, {
+ 'name' => $osfs->diskPath,
+ 'capacity' => $osfs->capacity,
+ 'freeSpace' => $osfs->freeSpace,
+ });
+
+ }
+ }
+
+ foreach my $entry (@{$vm->config->hardware->device}) {
+ my $vlan="Not Defined";
+ my $vlanId="Not Defined";
+
+ if (defined $entry->{macAddress}) {
+ if (! defined $vm->guest->{net}) {
+ next;
+ }
+ foreach my $ip (@{$vm->guest->net}) {
+ my @ipAddresses;
+ my %inter;
+ if (defined $ip->{macAddress}) {
+ if ($ip->{macAddress} eq $entry->macAddress) {
+ if (defined $ip->{'network'}) {
+ $vlan=$ip->{'network'};
+ }
+ if (defined $entry->backing->{port} ) {
+ my $portgroup=$entry->backing->port->portgroupKey;
+ my $dist_port=Vim::find_entity_view(view_type => "DistributedVirtualPortgroup",
+ begin_entity => $datacenter, filter => { 'key' => $portgroup}) ;
+ #print "NAME=".ref($dist_port->{'name'});
+ #next;
+
+ #if (eval defined "$dist_port->{'name'}") {
+ if (defined $dist_port) {
+ $vlan=$dist_port->name;
+ $vlanId=$dist_port->config->defaultPortConfig->vlan->vlanId;
+ }
+#=nisse
+# print $dist_port->name."\n";
+# print $dist_port->config->defaultPortConfig->vlan->vlanId."\n";
+# if (eval defined "$dist_port->name") {
+# $vlan=$dist_port->name;
+# $vlanId=$dist_port->config->defaultPortConfig->vlan->vlanId;
+# }
+#=cut
+ }
+ my $interface=$entry->deviceInfo->label;
+ if (defined $ip->{'ipAddress'}) {
+ foreach my $ipDef (@{$ip->ipAddress}) {
+ $inter{$interface}->{'label'}=$interface;
+ $inter{$interface}->{'ether'}=$entry->macAddress;
+ #($interface, %inter) =&get_ip_info($ipDef, "vmware", %inter);
+ }
+ push (@{$opthash{'network'}}, {
+ 'macAddress' => $entry->macAddress,
+ 'label' => $interface,
+ 'vlan' => $vlan,
+ 'vlanId' => $vlanId,
+ 'label' => $entry->deviceInfo->label,
+ #'ipAddresses' => [ @{$inter{$interface}->{'virtual'}} ],
+ });
+ }
+ }
+ }
+ }
+ }
+ }
+ # Add extra variables
+ my $opthash=(default(\%opthash));
+ $all_servers=build_hash($vm_hostname, $opthash, $all_servers);
+ #$all_servers=build_hash($vm->guest->hostName, $opthash, $all_servers);
+ return($all_servers);
+}
+# #####################################################################
+# Find vm relations to datacenter and/or cluster
+# #####################################################################
+
+=head1 EXTERNAL
+
+=over 4
+
+=item get_vmware_info($url, $username, $password, $all_servers)
+
+Utilices the Vmware Perl SDK, to populate %all_servers with info about vmware
+datacenters, hosts and clusters
+
+=cut
+sub get_vmware_info {
+
+ my ($url, $username, $password, $all_servers) = @_;
+ Util::connect($url, $username, $password);
+
+
+ my $vm_view_DC = Vim::find_entity_views(view_type => 'Datacenter');
+
+ foreach my $datacenter (@$vm_view_DC) {
+ my $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter',
+ properties => [ 'name' ],
+ filter => { name => $datacenter->name });
+
+ if (!$datacenter_view) {
+ die "Datacenter '" . $datacenter . "' not found\n";
+ }
+
+ my %datacenterhash= (
+ 'pri' => 1,
+ 'eq_type' => 'Virt. cloud',
+ 'serverMODEL' => 'Datacenter',
+ 'VC' => $url,
+ );
+
+ my $network_folder_ref = Vim::get_view(mo_ref => $datacenter->networkFolder);
+ %datacenterhash=&find_switch($network_folder_ref, %datacenterhash);
+
+ # find Clusters under datacenter
+ &debug($datacenter->name);
+ my $clusters=Vim::find_entity_views(view_type => 'ClusterComputeResource',
+ properties => [ 'name' ],
+ begin_entity => $datacenter_view);
+ foreach my $cluster (@$clusters) {
+ push (@{$datacenterhash{'serverPOOL_CHILD'}}, $cluster->name);
+ my %clusterhash = (
+ 'pri' => 3,
+ 'eq_type' => 'Virt. cloud',
+ 'serverMODEL' => 'ESX-Cluster',
+ 'VC' => $url,
+ 'serverPARENT' => $datacenter->name,
+ );
+
+ my $cluster_view = Vim::find_entity_view(view_type => 'ClusterComputeResource',
+ properties => [ 'name' ],
+ filter => { name => $cluster->name });
+
+ # find host in cluster
+ my $hosts = Vim::find_entity_views(view_type => 'HostSystem',
+ properties => [ 'name' ],
+ begin_entity => $cluster_view);
+
+ foreach my $host (@$hosts) {
+ push (@{$clusterhash{'serverPOOL_CHILD'}}, $host->name);
+ my $host_view = Vim::find_entity_view(view_type => 'HostSystem',
+ filter => { name => $host->name });
+
+
+
+ my %hosthash=();
+ my $consIP;
+ if (ref ($host_view->config->network->consoleVnic) eq 'ARRAY')
+ {
+ $consIP="NA";
+ } else {
+ $consIP="NA";
+ }
+
+ %hosthash = ( 'consIP' => $consIP,
+ 'pri' => 7,
+ 'description' => 'ToDO',
+ 'serverNUMCPU' => $host_view->summary->hardware->numCpuPkgs,
+ 'numNics' => $host_view->summary->hardware->numNics,
+ 'numHBAs' => $host_view->summary->hardware->numHBAs,
+ 'serverCPUSPEED' => $host_view->summary->hardware->cpuMhz,
+ 'serverMEMORY' => int($host_view->summary->hardware->memorySize/1048576),
+ 'serverOS' => $host_view->config->product->fullName,
+ 'eq_type' => 'Server',
+ 'serverMODEL' => $host_view->summary->hardware->model,
+ 'cpuModel' => $host_view->summary->hardware->cpuModel,
+ 'serverPARENT' => $cluster->name,
+ 'Datacenter' => $datacenter->name,
+ 'VC' => $url,
+ 'vendor' => $host_view->summary->hardware->vendor,
+ );
+
+
+ if (!defined $hosthash{'group_owner'}) {
+ if ($hosthash{'serverOS'}=~/Microsoft|VMware/) {
+ $hosthash{'group_owner'}="Windows";
+ } else {
+ $hosthash{'group_owner'}="Unix";
+ }
+ }
+ push (@{$hosthash{'datastore'}}, &get_datastore($host_view));
+ $all_servers=build_hash($host_view->name, \%hosthash, $all_servers);
+
+
+# Fjernet da vi uansett ikke bruker
+# info om virtuelle severe i databasen
+#
+# my $vms = Vim::find_entity_views(view_type => 'VirtualMachine',
+# begin_entity => $host_view);
+# foreach my $vm (@$vms) {
+# $all_servers=&vmware_guest ( $vm, $host_view, $cluster, $datacenter, $all_servers );
+# }
+ }
+ my $clusterhash=(default(\%clusterhash));
+ $all_servers=build_hash($cluster->name, $clusterhash, $all_servers);
+ }
+ my $datacenterhash=(default(\%datacenterhash));
+ $all_servers=build_hash($datacenter->name, $datacenterhash, $all_servers);
+ }
+ # disconnect from the server
+ return ($all_servers);
+ Util::disconnect();
+}
+
+sub get_datastore {
+ my ($host_view) = @_;
+
+ my $ds_mor_array = $host_view->datastore;
+ my $datastores = Vim::get_views(mo_ref_array => $ds_mor_array);
+
+ my @datastore;
+ foreach (@$datastores) {
+ if ($_->summary->multipleHostAccess eq 1) {
+ my %disk=(
+ name => $_->summary->name,
+ free => $_->summary->freeSpace,
+ );
+ push (@datastore, \%disk);
+ }
+ }
+ return @datastore;
+
+}
+
+sub PrintPortGroups {
+ my ($_) = @_;
+
+ my @datacenter;
+ # prints information about an array of DistributedVirtualPortgroup
+
+ # input: reference to moref[] of DistributedVirtualPortgroup
+ # return: none
+
+ #get the list of port groups
+ my $portGroups = Vim::get_views(mo_ref_array=>$_[0],
+ properties => [ 'config', 'name' ],
+ view_type => 'DistributedVirtualPortgroup');
+
+ foreach (@$portGroups) {
+ my $vlanId=$_->name;
+ my %vlanhash=();
+ if (ref $_->config->defaultPortConfig->vlan->vlanId eq 'ARRAY') {
+ push (@{$vlanhash{'vlan'}}, @{$_->config->defaultPortConfig->vlan->vlanId});
+ $vlanhash{'vlanId'}=$vlanId;
+ } else {
+ %vlanhash = (
+ 'vlan' => $_->config->defaultPortConfig->vlan->vlanId,
+ 'vlanId' => $_->config->name,
+ );
+ if ($_->config->description) {
+ $vlanhash{'description'}=$_->config->description;
+ #my $utffix=Encode::find_encoding('UTF-8');
+ #$vlanhash{'description'}=$utffix->encode($vlanhash{'description'});
+ }
+ #$uni=Encode::find_encoding('UNICODE')
+ }
+ push (@datacenter, \%vlanhash);
+ }
+ return @datacenter;
+}
+
+sub find_switch {
+
+ my ($network_folder_ref, %datacenterhash) = @_;
+
+ foreach my $child (@{$network_folder_ref->childEntity}) {
+ if ($child->type eq "Folder") {
+ my $childref = Vim::get_view(mo_ref => $child,
+ properties => [ 'childEntity' ],
+ );
+ %datacenterhash=&find_switch($childref, %datacenterhash);
+ } elsif ($child->type eq "VmwareDistributedVirtualSwitch") {
+ #retrieve a list of items of type VmwareDistributedVirtualSwitch from the folder
+ #my $dvs_refs = Vim::get_views(mo_ref_array => $child->childEntity, view_type => 'VmwareDistributedVirtualSwitch');
+ my $dvs_refs = Vim::get_view(mo_ref => $child ,
+ properties => [ 'portgroup' ],
+ view_type => 'VmwareDistributedVirtualSwitch');
+
+ my @VLANS=PrintPortGroups($dvs_refs->portgroup);
+ push (@{$datacenterhash{'VLAN'}},@VLANS);
+ }
+ }
+ return %datacenterhash;
+}
+
+sub countlines {
+ my ($vc, $cmd) = @_;
+
+ my $path="/site/var/out";
+ opendir(OUT, $path);
+ mkdir ($path."/arkiv") if ($cmd eq "rotate");
+
+ my %count=();
+ while (my $file = readdir(OUT)) {
+ chomp $file;
+ next if ($file !~ /$vc/);
+ open (FILE, $path."/".$file) or die "Not able to open $file $!\n";
+ $count{$file}=0;
+ while (<FILE>) {
+ next if (/^[\s#]/) ;
+ $count{$file}++;
+ }
+ close FILE;
+ rename $path."/".$file, $path."/arkiv/".$file if ($cmd eq "rename");
+ }
+ close OUT;
+ return %count;
+}
+
+sub get_virt_server {
+
+ my ($url, $vc, $username, $password, $dbh, $bofh, %houdini) = @_;
+ my $vim=Util::connect($url, $username, $password);
+
+
+ #my $servers = $vim->find_entity_views(view_type => 'VirtualMachine', properties => ['name', 'resourcePool', 'config', 'guest'],
+ my $servers = $vim->find_entity_views(view_type => 'VirtualMachine',
+ # filter => { name => 'raghon03.uio.no' },
+ # filter => { name => 'rdstest-host.uhad.no' }
+ );
+
+
+ my %precount=countlines($vc, "rotate");
+ open (HOSTNAME, ">/site/var/out/".$vc."_hostname_error.txt") or die "Not able to open $!\n";
+ open (HOSTNAME2, ">/site/var/out/".$vc."_hostname2_error.txt") or die "Not able to open $!\n";
+ open (NOTINSTM, ">/site/var/out/".$vc."_not_in_stm_error.txt") or die "Not able to open $!\n";
+ open (NOTINDNS, ">/site/var/out/".$vc."_not_in_dns_error.txt") or die "Not able to open $!\n";
+ open (FOLDER, ">/site/var/out/".$vc."_folder_error.txt") or die "Not able to open $!\n";
+ open (TOOLS, ">/site/var/out/".$vc."_tools_error.txt") or die "Not able to open $!\n";
+ open (UPPERCASE, ">/site/var/out/".$vc."_uppercase_error.txt") or die "Not able to open $!\n";
+ open (VIKTIGHET, ">/site/var/out/".$vc."_viktighet_error.txt") or die "Not able to open $!\n";
+
+ # Create file headers;
+ print HOSTNAME "# Maskiner med forskjellig hostnavn og VMware-navn\n";
+ print HOSTNAME "# ################################################\n\n";
+ print HOSTNAME2 "# hostname != vm name but a defined ip on system matches vmname\n";
+ print HOSTNAME2 "# #############################################################\n\n";
+ print NOTINSTM "# Maskiner ikke i houdini\n";
+ print NOTINSTM "# #######################\n\n";
+ print NOTINDNS "# IP-adresser ikke registrert i DNS\n";
+ print NOTINDNS "# #################################\n\n";
+
+ print FOLDER "# Folder matcher ikke hostname\n";
+ print FOLDER "# ############################\n\n";
+ print TOOLS "# Vmware tools kjører ikke\n";
+ print TOOLS "# ########################\n\n";
+ print UPPERCASE "# Hoster som er definert i uppercase\n";
+ print UPPERCASE "# ##################################\n\n";
+ print VIKTIGHET "# Viktighet missmatch\n";
+ print VIKTIGHET "# ###################\n\n";
+
+
+
+ foreach my $server (@$servers) {
+ my $servername=$server->name;
+ my $ip=$server->guest->ipAddress;
+ my $vmhostname=$server->guest->hostName;
+
+ my $folder="unknown";
+ $folder=$vim->Vim::get_view(mo_ref => $server->parent)->name if ($server->parent);
+ $folder = "unknown" if (!$folder);
+
+ # Cluster node
+ my $cluster_node= $vim->Vim::get_view(mo_ref => $server->runtime->host, properties => ['name', 'parent']);
+ my $cluster= $vim->Vim::get_view(mo_ref => $cluster_node->parent, properties => ['name', 'parent']);
+ my $datacenter;
+ if ($cluster->parent->type eq 'Folder') {
+ my $cluster_folder=$vim->Vim::get_view(mo_ref => $cluster->parent, properties => ['name', 'parent']);
+ $datacenter=$vim->Vim::get_view(mo_ref => $cluster_folder->parent, properties => ['name', 'parent']);
+ } else {
+ print "noe er rart her\n";
+ }
+
+ my $dcid=get_dcid($dbh, $datacenter->name, $url);
+ my $clid=get_clid($dbh, $cluster->name, $dcid, $url);
+ my %msg=(
+ servername => $servername,
+ uppercase => 0,
+ notindns => [],
+ houdini_interfaces => [],
+ vmmatch => 0,
+ vmmatch_name => undef,
+ vmhoudini => 0,
+ tools => 0,
+ #viktighet => 0,
+ file_folder => 1,
+ file_status => 0,
+
+ clid => $clid,
+ guestid => $server->config->guestId,
+ disksize => 1,
+ num_cpus => $server->config->hardware->numCPU,
+ memory => $server->config->hardware->memoryMB,
+ folder => $folder,
+ vlanid => 1,
+ tagid => 1,
+ kort_beskrivelse => 1,
+ lang_beskrivelse => 1,
+ dok_ansvarlig => 1,
+ ressursperson => 1,
+ ansvarlig_enhet => 1,
+ epostliste => 1,
+ oppesjekk => 1,
+ alias => 1,
+ bruksmonster => 1,
+ bruker_dok => 1,
+ drifts_dok => 1,
+ utvikler_dok => 1,
+ sterkt_avhengig_av => 1,
+ svakt_avhengig_av => 1,
+ viktighet => 0,
+ server_type => 1,
+ andre_krav => 1,
+ bestilt => 1,
+ usit_tilgang => 1,
+ ytelses_krav => 1,
+ ad_gruppe => 1,
+ spesielle_tilganger => 1,
+ bestillerkode => 1,
+ epost_economy => 1,
+ economy_ansvarlig => 1,
+ faktura_tekst => 1,
+ faktura_epost => 1,
+ slutt_dato => '12-31-9999',
+ annen_info => 1,
+ );
+
+ # Test if servername is defined in uppercase
+ #
+
+ if ($servername =~ /[A-Z]/) {
+ #print "Server ".$servername." is defined with uppercase\n";
+ $msg{'uppercase'} = 1;
+ #fixing
+ my $lcname=VirtualMachineConfigSpec->new ( name => lc($server->name));
+ #$server->ReconfigVM(spec => $lcname);
+ }
+
+ my $vmmatch=0;
+ if ($vmhostname and lc($servername) ne lc($vmhostname)) {
+ #print "hostname $servername does not match VMhost $vmhostname\n";
+ $msg{'vmmatch'} = 1;
+ }
+ my $vmhoudini=0;
+ if (!$houdini{lc($servername)}) {
+ #print NOTDEF "WARNING: ".$servername." is not defined in houdini\n";
+ #print "WARNING: ".$servername." is not defined in houdini\n";
+ $msg{'vmhoudini'} = 1;
+ }
+
+ # Have a look at IP's defined for this host
+ #
+ if (ref $server->guest->net eq 'ARRAY') {
+ foreach my $net (@{$server->guest->net}) {
+ if (ref $net->ipAddress eq 'ARRAY') {
+ foreach my $nets (@{$net->ipAddress}) {
+ my $resName=gethostbyip6($nets);
+ #print "WARNING!!! ".$nets." is not defined in DNS\n" if (!$resName);
+ push (@{$msg{'notindns'}}, $nets) if (!$resName);;
+ next if (!$resName);
+ push (@{$msg{'houdini_interfaces'}}, $resName) if ($houdini{$resName} and $resName ne lc($servername));
+ if ($msg{'vmmatch'} == 1 and $resName eq lc($servername)) {
+ #$msg{'vmmatch_name'}=$resName;
+ $msg{'vmmatch_name'}=$ip;
+ $msg{'vmmatch'} = 0;
+ }
+ }
+ } else {
+ next if (!$ip);
+ my $resName=gethostbyip6($ip);
+ #print "WARNING!!! ".$ip." is not defined in DNS\n" if (!$resName);
+ push (@{$msg{'notindns'}}, $ip) if (!$resName);;
+ next if (!$resName);
+ next if (!$resName);
+ push (@{$msg{'houdini_interfaces'}}, $resName) if ($houdini{$resName} and $resName ne lc($servername));
+ if ($msg{'vmmatch'} == 1 and $resName eq $servername) {
+ $msg{'vmmatch_name'}=$ip;
+ $msg{'vmmatch'} = 0;
+ }
+ }
+ }
+ } else {
+ #print "CRITICAL!!! No network interface is defined for VM $servername\n";
+ }
+
+ if ($server->guest->toolsRunningStatus ne "guestToolsRunning") {
+ #print "$servername VMWARE tools not running \n";
+ $msg{'tools'}=1;
+ }
+
+
+ if ($server->resourcePool) {
+ my $vmpool=$vim->Vim::get_view(mo_ref => $server->resourcePool, properties => ['name'])->name;
+ $vmpool=~s/sydr-kat//;
+ if ($houdini{$servername} and $vmpool != $houdini{$servername}->{'viktighet'}) {
+ $msg{'viktighet'}=$vmpool;
+ }
+
+ } else {
+ next if ($server->config->template == 1) ;
+ $msg{'viktighet'}=-1;
+ }
+
+ $msg{'file_folder'}=$server->config->files->vmPathName;
+ $msg{'file_folder'}=~s/\[.*\]\s|\/.*//g;
+ $msg{'file_status'}=1 if ($msg{'file_folder'} ne $servername);
+
+ print "\n\nSTATUS ".$server->name."\n" if (
+ $msg{'uppercase'} != 0 or
+ $msg{'notindns'} or
+ $msg{'houdini_interfaces'} or
+ $msg{'vmmatch'} != 0 or
+ $msg{'vmmatch_name'} or
+ $msg{'vmhoudini'} != 0 or
+ $msg{'tools'} != 0 or
+ $msg{'viktighet'} != 0 or
+ $msg{'file_status'} != 0
+ ) ;
+ print "\tuppercase in vmware\n" if ($msg{'uppercase'} == 1);
+ print UPPERCASE $server->name."\n" if ($msg{'uppercase'} == 1);
+ # OK print "\thostname != vm name (".$vmhostname.")\n" if ($msg{'vmmatch'} == 1);
+ print HOSTNAME $server->name." (VMware: $vmhostname)\n" if ($msg{'vmmatch'} == 1);
+ print "\thostname != vm name but a defined ip on system matches vmname : $msg{'vmmatch_name'}\n" if ($msg{'vmmatch_name'});
+ print HOSTNAME2 $server->name." (Vmware: $vmhostname => ".$msg{'vmmatch_name'}.")\n" if ($msg{'vmmatch_name'});
+ #if (ref $msg{'houdini_interfaces'} eq 'ARRAY') {
+ foreach (@{$msg{'houdini_interfaces'}}) {
+ print "\tHOUDINI interface ".$_."\n";
+ }
+ foreach (@{$msg{'notindns'}}) {
+ next if (/^fe80::*|127\.0\.0|10\.|192\.168\./);
+ print "\tIP not registred in DNS ".$_."\n";
+ print NOTINDNS $server->name." - ",$_."\n";
+ }
+ #}
+ if ($msg{'vmhoudini'} == 1) {
+ print "\tnot defined in houdini\n";
+ print NOTINSTM $server->name."\n";
+ my @r = $bofh->host_info($server->name);
+ foreach my $k (@{$r[0]}) {
+ foreach (keys %{$k}) {
+ print NOTINSTM "\t$_ => ".$$k{$_}."\n";
+ }
+ }
+ print NOTINSTM "\n";
+ }
+
+ print "\tVmware tools not running\n" if ($msg{'tools'} == 1);
+ print TOOLS $server->name."\n" if ($msg{'tools'} == 1);
+ print "\tviktighet missmatch: houdini=".$houdini{lc($servername)}->{'viktighet'}." != vmware=".$msg{'viktighet'}."\n" if ($msg{'viktighet'} != 0);
+ print VIKTIGHET $server->name." houdini=".$houdini{lc($servername)}->{'viktighet'}." != vmware=".$msg{'viktighet'}."\n" if ($msg{'viktighet'} != 0);
+ print "\tFoldername does not match servername $msg{'file_folder'}\n" if ($msg{'file_status'} == 1);
+ print FOLDER $server->name." - $msg{'file_folder'}\n" if ($msg{'file_status'} == 1);
+
+
+
+ #insert_db($dbh, %msg);
+ }
+ close HOSTNAME;
+ close NOTINSTM;
+ close NOTINDNS;
+ close FOLDER;
+ close TOOLS;
+ close UPPERCASE;
+ close VIKTIGHET;
+ my %postcount=countlines($vc);
+
+ open (COUNT, ">/site/var/out/".$vc."_count_error.txt") or die "Not able to open $!\n";
+ print COUNT "# Status rapport for Virtual Center $vc.
+ Alle status filer er også tilgjengelig på esx-mgmt://site/var/out, samt at
+ output fra forrige kjøring ligger i katalogen
+ esx-mgmt://site/var/out/arkiv.
+
+ \n";
+ print COUNT "# Filenavn : forrige kjøring => Nå status\n";
+ foreach (keys %precount) {
+ next if (/$vc."_count_error.txt"/);
+ printf "%-30s: %5i => %5i\n", $_, $precount{$_}, $postcount{$_};
+ printf COUNT "%-30s: %5i => %5i\n", $_, $precount{$_}, $postcount{$_};
+ }
+ close COUNT;
+
+}
+
+1;
+
+=back
+
+=head1 SEE ALSO
+
+L<UiO::XML> L<UiO::Utils> L<UiO::Param>
+L<UiO::SunVirt> L<UiO::BB> L<UiO::SAFE>
+
+=head1 AUTHOR
+
+Created by Ragnar Hongset @ RagHon Consulting
+
+=cut