VMware {code} Community
ubekhet
Contributor
Contributor
Jump to solution

Knowing phisical machine through of VM IP address

Hi,

I was wondering if is capable of discover the phisical machine where our VM are installed throught IP address. Basically, I want to know my HOST machine name.

Thanks in advance!!!

Reply
0 Kudos
1 Solution

Accepted Solutions
akutz
Hot Shot
Hot Shot
Jump to solution

Here is a link to a prettier version.

View solution in original post

Reply
0 Kudos
23 Replies
akutz
Hot Shot
Hot Shot
Jump to solution

Let me see if I understand the question. You want to discover the identity of the ESX server that is hosting a VM based upon one of the IP addresses the guest OS inside the VM is using? Do you intend to do this with or without the VI SDK?

Reply
0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

If I read the question right, you want to know based on an IP address what ESX Host your VM is running on?

That's should be fairly simple to do. Search the VM's GuestInfo->net objects for the ipAddress (you have to look here if you want to cover machines with multiple ip aliases/nics defined) and then look at the VM's VirtualMachineRunTimeInfo->host for the name.

Code samples would depend on what environment you're running looking to run this in...Perl, PowerShell, Java, C#...

Reuben Stump | http://www.virtuin.com | @ReubenStump
Reply
0 Kudos
ubekhet
Contributor
Contributor
Jump to solution

Yes, that is what I want to do using VI SDK. I am newbie in VI SDK, can you tell some example for to do that?

Regards

Reply
0 Kudos
ubekhet
Contributor
Contributor
Jump to solution

Hi stumpr,

Your answer is based on VI SDK or another alternative?

Thanks

Reply
0 Kudos
akutz
Hot Shot
Hot Shot
Jump to solution

There are two problems. One, you are not guaranteed that the VM's guest OS has a single IP address. If that was the case then you could use the following Perl code:

---

#!/usr/bin/perl -w

use strict;

use warnings;

use FindBin;

use lib "$FindBin::Bin/../";

use VMware::VIRuntime;

use AppUtil::VMUtil;

$SIG=sub;

$Util::script_version = "1.0";

my %opts = (

'ipaddress' => {

type => "=s",

help => "An IP address of the guest OS",

required => 1,

},

);

Opts::add_options(%opts);

Opts::parse();

Opts::validate();

Util::connect();

my $vm_view = Vim::find_entity_view( view_type => 'VirtualMachine',

filter => { 'guest.ipAddress' => Opts::get_option( 'ipaddress' ) } );

print Dumper $vm_view;

Util::disconnect();

---

You cannot search on an array of IP addresses like you would have to if the guest OS had multiple IPs. The filter would have to look like 'guest.net.ipAddress' where 'net' is an array of the networks configured on the guest OS. This doesn't work (I tried it), and the VI Perl reference says you can only search on simple types such as integers or strings. I guess an array is not considered a simple type.

Additionally, all of this is dependent on the VM tools being installed, which you cannot guarantee. Well, maybe you can via policy, but it is not something I try to depend on myself.

Assuming the VM tools are installed the only straight-forward method to accomplish your goal would be to enumerate all the VMs and then enumerate their guest OS networks though the 'guest.net' array and look at the 'ipAddress' property. While straight-forward, this solution is possibly time consuming and resource intensive.

Now, there is a possible solution, albeit tricky. I have not tried this, but it should work. Perhaps stumpr can look at this with me and determine if I am out of my head. There are many VMs, but there are presumably fewer networks, and you do not seem to care about the actual VM, but rather the host it lives on. Therefore, the following logic should work:

1. Enumerate each ESX host

2. Get a reference to the HostNetworkSystem and invoke the QueryNetworkHint method. The QueryNetworkHint method returns an array of PhysicalNicHintInfo data objects. Basically, you are telling the host to figure out which IP networks its physical NICs are connected to.

3. Do some crazy network math and determine if the IP address you are searching for is among the networks the host has access to.

4. If it isn't then start over with the next host.

5. If it is then enumerate the host's VMs and look at the guest.net.ipAddress properties of each VM as we discussed earlier.

Hope this helps!

Reply
0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

VI SDK. I've attached a simple perl script. Don't shoot me if it has errors, but it ran successfully against my current production cluster.

You'll of course need to have the Perl SDK installed. If you open the script just edit the "my $username = . For example, "FindEsxByGuestIp.pl 192.168.1.1" will search all VMs and loop through the defined network interfaces for the IP '192.168.1.1'.

r.

Reuben Stump | http://www.virtuin.com | @ReubenStump
Reply
0 Kudos
stumpr
Virtuoso
Virtuoso
Jump to solution

Pretty much. I posted a sample, but as you pointed out it assumes the guest IP you are searching for has the Tools installed. Without the tools I don't see how you will be able to find the IP address so easily.

I like the idea of sort of skipping hosts without defined network connections to that network. In my environment, however, I have about a dozen VLANs all defined on every host in my cluster (currently 7 esx hosts, building upto 25 esx hosts as part of a large datacenter relocation project). So in my environment I would essentially have no hosts filtered out, they are all configured identically for connectivity. But the logic is still good. It would be fairly simple to test an IP is within a network range. Usually the simplest way is to convert the IP to decimal in your code and do a simple > < compare. Look at Net::IP (gotta love CPAN). You would just get the subnet ip, broadcast ip and test if an ip falls in that range.

Though I do see in HostPortGroupPort a MAC property. Apparently this is a runtime set of information. You might be able to find a MAC address of a guest by querying this interface (and the accompanying ESX host). But to get to the IP address without the tools still seems tricky.

I tried what you tried, akutz. I first tried to do a filter to see if the VI Perl filter was savvy enough to work on array objects. It wasn't. So looks like you have to just do a lot of foreach/if's to get at the tool's reported IP address(es).

R.

Reuben Stump | http://www.virtuin.com | @ReubenStump
Reply
0 Kudos
ubekhet
Contributor
Contributor
Jump to solution

First of all, thanks for your answer!!!

Let me explain a little bit exactly what I want to do and what kind of information we can guaranteed to have. the VM's guest OS always will have a single IP address this is guaranteed.

Actually, I am doing a very simple application which receive the IP address through of VM guest, and then using VI SDK I want discover from IP address in which phisical machine, the ESX host.

Regards

Reply
0 Kudos
akutz
Hot Shot
Hot Shot
Jump to solution

If the guest OS is guaranteed to have a single IP address then the following code will grab a view of the host. FYI - My example in VI Perl uses filters, a method unique to VI Perl. However, you can find the VM easily via straight SDK calls with the FindByIPAddress methodd.

#!/usr/bin/perl -w

use strict;

use warnings;

use FindBin;

use lib "$FindBin::Bin/../";

use VMware::VIRuntime;

use AppUtil::VMUtil;

$SIG=sub;

$Util::script_version = "1.0";

my %opts = (

'ipaddress' => {

type => "=s",

help => "An IP address of the guest OS",

required => 1,

},

);

Opts::add_options(%opts);

Opts::parse();

Opts::validate();

Util::connect();

my $vm_view = Vim::find_entity_view( view_type => 'VirtualMachine',

filter => { 'guest.ipAddress' => Opts::get_option( 'ipaddress' ) } );

my $host_view = Vim::get_view( mo_ref => $vm_view->runtime->host, view_type => 'HostSystem' );

print Dumper $host_view;

Util::disconnect();

Reply
0 Kudos
ubekhet
Contributor
Contributor
Jump to solution

Thanks for your answer an example using perl, but I am wondering if you have the same example using java VI SDK, because all of my code is based in java.

Thanks

Reply
0 Kudos
akutz
Hot Shot
Hot Shot
Jump to solution

Here you go. Once I upload it to my site I'll link the formatted version.

---

package findhostbyvmipaddress;

import com.vmware.vim25.*;

/**

*

  • @author akutz

*/

public class Main

{

/**

  • @param args the command line arguments

*/

public static void main( String[] args )

{

String str_username = args[ 0 ];

String str_password = args[ 1 ];

String str_server = args[ 2 ];

String str_vm_ip_address = args[ 3 ];

// This is the class for the very special managed object ServiceInstance,

// the root of all things VI3 SDK

VimPortType o_vim_svc = null;

// This is the class that contains information relative to the current

// ServiceInstance, in this case, VimService

ServiceContent o_vim_svc_content = null;

// Get a reference to the VI service instance.

ManagedObjectReference moref_vim_svc = null;

moref_vim_svc = new ManagedObjectReference();

moref_vim_svc.setType( "ServiceInstance" );

moref_vim_svc.set_value( "ServiceInstance" );

VimServiceLocator vim_svc_loc = new VimServiceLocator();

vim_svc_loc.setMaintainSession( true );

// Ignore SSL warnings

System.setProperty("axis.socketSecureFactory",

"org.apache.axis.components.net.SunFakeTrustSocketFactory");

try

{

o_vim_svc = vim_svc_loc.getVimPort(

new java.net.URL( "https://" + str_server + "/sdk" ) );

o_vim_svc_content = o_vim_svc.retrieveServiceContent( moref_vim_svc );

// Login to the VI SDK.

o_vim_svc.login(

o_vim_svc_content.getSessionManager(), str_username, str_password, null );

// Get a managed object reference to the VM with the given IP address

ManagedObjectReference moref_vm = o_vim_svc.findByIp(

o_vim_svc_content.getSearchIndex(),

null, str_vm_ip_address, true );

// Build a property spec, object spec, and property filter spec

// to get the host property from the VM

PropertySpec pspec = new PropertySpec();

pspec.setAll( false );

pspec.setType( "VirtualMachine" );

pspec.setPathSet( new String[] { "runtime.host" } );

ObjectSpec ospec = new ObjectSpec();

ospec.setObj( moref_vm );

PropertyFilterSpec pfspec = new PropertyFilterSpec();

pfspec.setObjectSet( new ObjectSpec[] );

pfspec.setPropSet( new PropertySpec[] );

// Collect the properties.

ObjectContent[] oc_coll = o_vim_svc.retrieveProperties(

o_vim_svc_content.getPropertyCollector(),

new PropertyFilterSpec[] );

// Get the returned property and cast it to a managed object reference.

ManagedObjectReference moref_host = ( ManagedObjectReference )

oc_coll[ 0 ].getPropSet( 0 ).getVal();

// Logout

o_vim_svc.logout( o_vim_svc_content.getSessionManager() );

}

// vim_svc_loc.getVimPort( new java.net.URL( str_url ) );

catch ( java.net.MalformedURLException e )

{

// Handle exception

e.printStackTrace( System.out );

}

// o_vim_svc = vim_svc_loc.getVimPort( new java.net.URL( str_url ) );

catch ( javax.xml.rpc.ServiceException e )

{

// Handle exception

e.printStackTrace( System.out );

}

// o_vim_svc_content = o_vim_svc.retrieveServiceContent( moref_vim_svc );

// o_vim_svc.login( o_vim_svc_content.getSessionManager(), str_username, str_password, null );

catch ( java.rmi.RemoteException e )

{

// Handle exception

e.printStackTrace( System.out );

}

}

}

Reply
0 Kudos
akutz
Hot Shot
Hot Shot
Jump to solution

Here is a link to a prettier version.

Reply
0 Kudos
ubekhet
Contributor
Contributor
Jump to solution

akutz, thank you very much, tomorrow I will try it and I will tell you if everything going on right!!!

Regards

Reply
0 Kudos
z0ltan
Enthusiast
Enthusiast
Jump to solution

Hi mate,

I was intrigued to see your question. In fact so intrigued that I thought of trying to implement a simple solution to it. Here is what I found :

1. Obtain a ManagedObjectReference to the VirtualMachine say, "vmRef".

2. Use the PropertyCollector object to obtain a ManagedObjectReference to the Host Machine by passing the following arguments to the "PropertySpec" object of the PropertyFilterSpec -

PathSet = "runtime.host"

3. This runtime.host property is guaranteed to be set (According to the Reference Guide).

4. Perform any further operations using this ManagedObjectReference.

Peace!

z0ltan.






Bwahahahahahahahahahahahahaha!

Bwahahahahahahahahahahahahaha!
Reply
0 Kudos
ubekhet
Contributor
Contributor
Jump to solution

Hi akutz,

I am running your code and it give the follow error:

java.io.IOException: Non nillable element 'obj' is null.

in this line:

// Collect the properties.

ObjectContent[] oc_coll = o_vim_svc.retrieveProperties(

o_vim_svc_content.getPropertyCollector(),

new PropertyFilterSpec[] );

I am trying to resolve it but at this moment I dont know exactly why happen and if you have the same error like me.

Thanks in advance

Regards

Reply
0 Kudos
akutz
Hot Shot
Hot Shot
Jump to solution

Did you verify it is finding the VM? The code works on my end.

ubekhet
Contributor
Contributor
Jump to solution

I see the problem that doesnt find the VM!!! could be better if I pass the virtual machine name instead of using getSearchIndex() ?

Regards

Reply
0 Kudos
ubekhet
Contributor
Contributor
Jump to solution

Hi again,

I am wondering if is possible that it doesnt working because it nececessary to have installed vmware tools, because actually I dont.

regards

Reply
0 Kudos
akutz
Hot Shot
Hot Shot
Jump to solution

It won't find the VM by IP address then. So, yes, you need the VM

tools installed.

--

-a

"condensing fact from the vapor of nuance"

gpg pubkey: http://www.lostcreations.com/~akutz/akutz.gpg

lostcreations ca: http://www.lostcreations.com/lostcreations.com-ca.crt

Reply
0 Kudos