VMware {code} Community
akutz
Hot Shot
Hot Shot

VI SDK 2.5 has APIs for integrated NAT and DHCP services, but I cannot get them to work

So I was drinking my coffee this morning, paging through the available data objects in the VI SDK to see if I see anything new (what, you don't do this too?), and lo, what do I see but an object for HostNatServiceSpec. This looked interesting so I started to explore and before long it was apparent that although there were no hints of them in the VI client, the SDK, since version 2.5, has all the API methods and data types necessary to configure several NAT and DHCP services on an ESX server.

HostDhcpService

HostNatService

Cool!

This is a HUGE deal because prior to these services the only way to get a DHCP server or NAT service on ESX was to implement a VM that was dual-homed on a public network and private network. The VMs guest OS then had to implement Windows RAS and DHCP or Linux dhcpd and iptables to act as a DHCP and NAT device. It was cumbersome, and worst of all it did not scale easily in a large ESX implementation. So now that VI apparently has DHCP and NAT a lot of ESX administrators will rest a lot easier at night.

Before creating a VI client plugin to expose this functionality I decided to test it out via some quick Perl scripts. That is when the fun started to dissipate... I cannot get the darn things to work! Here is my Perl script that should add a NAT service to the specified host. Although some of the options I have created are "required", I am ignoring them in the script and building some structures manually while I am in the testing phase.

---

#!/usr/bin/perl -w

use strict;

use warnings;

use FindBin;

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

use VMware::VIRuntime;

use AppUtil::VMUtil;

#

  1. PROTOTYPES

#

sub parse_port_forwards;

  1. If we die this day then die disconnected.

$SIG=sub;

$Util::script_version = "1.0";

my %opts = (

'hostname' => {

type => "=s",

help => "Host name",

required => 1,

},

'key' => {

type => "=s",

help => "The instance ID of the NAT service",

required => 1,

},

'activeFtp' => {

type => "",

help => "The flag to indicate whether or not non-passive mode FTP connections should be allowed"

},

'allowAnyOui' =>

{

type => "",

help => "The flag to indicate whether or not the NAT Service allows media access control traffic from any Organizational Unique Identifier (OUI)? By default, it does not allow traffic that originated from the host to avoid packet loops",

},

'configPort' =>

{

type => "",

help => "The flag to indicate whether or not the NAT Service should open a configuration port.",

},

'ipGatewayAddress' =>

{

type => "=s",

help => "The IP address that the NAT Service should use on the virtual network",

required => 1,

},

'portForward' =>

{

type => "s",

help => "The port forwarding specifications to allow network connections to be initiated from outside the firewall",

},

'udpTimeout' =>

{

type => "=i",

help => "The time alloted for UDP packets",

required => 1,

},

'virtualSwitch' =>

{

type => "=s",

help => "The name of the virtual switch to which nat service is connected",

required => 1,

},

);

Opts::add_options(%opts);

Opts::parse();

Opts::validate();

Util::connect();

  1. Get a reference to this session's service.

my $m_o_vim_svc = Vim::get_vim_service();

  1. Get a reference to this session's service content.

my $m_o_vim_svc_content = Vim::get_service_content();

  1. Get a reference to the intended host.

my $m_o_moref_host = $m_o_vim_svc->FindByDnsName(

this => $mo_vim_svc_content->searchIndex,

dnsName => Opts::get_option( 'hostname' ),

vmSearch => 0 );

  1. Get a view for the host.

my $m_o_view_host = Vim::get_view( mo_ref => $m_o_moref_host->result, type => 'HostSystem' );

my $m_o_view_host_net_sys = Vim::get_view( mo_ref => $m_o_view_host->configManager->networkSystem );

my $m_host_nat_svc_spec = HostNatServiceSpec->new(

activeFtp => "false",

allowAnyOui => "false",

configPort => "false",

ipGatewayAddress => "192.168.0.59",

portForward => parse_port_forwards(),

udpTimeout => "15",

virtualSwitch => "vSwitch0" );

my $m_host_nat_svc_cfg = HostNatServiceConfig->new(

changeOperation => "add",

key => "NAT1",

spec => $m_host_nat_svc_spec );

my $m_host_net_cfg = HostNetworkConfig->new( nat => );

  1. Create the NAT service

print Dumper $m_o_vim_svc->UpdateNetworkConfig(

this => $mo_view_host->configManager->networkSystem,

config => $m_host_net_cfg,

changeMode => "modify" );

Util::disconnect();

sub parse_port_forwards()

{

my $pf = [

HostNatServicePortForwardSpec->new(

guestIpAddress => "192.168.0.148",

guestPort => "80",

hostPort => "8080",

name => "HTTP",

type => "tcp",

),

];

return $pf;

}

---

I apologize for Jive's (the software these forums use) complete destruction of my code's syntax. Notice that Jive replaces the pound sign with a bulleted list, which totally screws up Perl comments. Anyway, this code runs and outputs the following:

---

akutz@amends:host$ ./natadd.pl --server 192.168.0.47 --username Administrator --password 'HAHAHA' --hostname mandy.lostcreations.local --ipGatewayAddress foo --key foo --udpTimeout 15 --virtualSwitch foo

$VAR1 = bless( {

'fault' => undef,

'result' => bless( {}, 'HostNetworkConfigResult' )

}, 'SoapResponse' );

---

This seems to imply that all is well. However, I then print out the value of the 'nat' property using the following lines:

---

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

my $net_view = Vim::get_view( mo_ref => $host_view->configManager->networkSystem );

print Dumper $net_view->networkConfig->nat;

---

And I get:

---

$VAR1 = undef;

---

Okay. Well, I assumed I was doing something wrong, but after much debugging I think that VMware simply has not implemented this stuff on the back-end yet. For example, if you look at the method definition for UpdateNetworkConfig you'll not that it does not support a whole bunch of what it is supposed to support. It is like the programmer who began work on it up and quit VMware and it has not been completed.

Other developers on these forums have had issues with UpdateNetworkConfig.

This functionality looks promising, and I want to get it to work. Any help or ideas are very much appreciated. Thanks!

UPDATE:

I forgot to add that you can change the value of 'add' on the HostNatServiceConfig object to an unsupported value or to 'edit' (which should throw an exception since the NAT service doesn't exist to edit yet) and the server does not complain. This makes me believe that the server really isn't acting on this data when you send it to it.

Message was edited by: akutz

0 Kudos
0 Replies