Advertisement
Guest User

vnicmove.pl

a guest
Aug 5th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 5.89 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. # vnicmove.pl
  3.  
  4. use strict;
  5. use warnings;
  6. use LWP;
  7. use LWP::Simple;
  8. use Data::Dumper qw(Dumper);
  9.  
  10. use lib "/usr/lib/vmware-vcli/apps/";
  11. use VMware::VIRuntime;
  12. use AppUtil::HostUtil;
  13.  
  14. use lib "JSON-2.90/lib/";
  15. use JSON;
  16.  
  17. my $DEBUG = 1;
  18.  
  19. # Opts::parse() appears to break $0
  20. my $scriptname = $0;
  21.  
  22. # Function prototypes
  23. sub move_vnic ($$);
  24.  
  25. # Monkey see, monkey do
  26. $Util::script_version = "1.0";
  27.  
  28. # Read only a task ID from the commandline, and the rest from imgmgr
  29. my %opts = (
  30.    name => {
  31.       type => "=s",
  32.       help => "Name of the VM to move.",
  33.       required => 1,
  34.    },
  35.    vlan => {
  36.       type => "=i",
  37.       help => "VLAN ID. (e.g. 300)",
  38.       required => 1,
  39.       default => "321",
  40.    },
  41. );
  42.  
  43. Opts::add_options(%opts);
  44. Opts::parse();
  45. if ((!defined $opts{'name'}->{'value'}) || (!defined $opts{'vlan'}->{'value'})) {
  46.   print "Usage: $scriptname -name [VM name] -vlan [Numeric VLAN ID]\n";
  47.   exit 1;
  48. }
  49. if ($DEBUG) { print Dumper(\%opts); }
  50.  
  51. Util::connect();
  52. move_vnic($opts{'name'}->{'value'}, $opts{'vlan'}->{'value'});
  53.  
  54. # Don't disconnect because it deletes our cached credentials
  55. #Util::disconnect();
  56.  
  57. sub move_vnic ($$) {
  58.   my $name = shift;
  59.   my $vlan = shift;
  60.  
  61.   # Find the dvs portgroup from the VLAN id
  62.   my $my_dvs_pg_view = '';
  63.   my $dvs_pg_views = Vim::find_entity_views (
  64.                             view_type => 'DistributedVirtualPortgroup'
  65.                                            );
  66.   unless (@$dvs_pg_views) {
  67.     Util::trace(0, "\nError updating VM '$name': "
  68.                  . "No DVS port groups could be found!\n");
  69.     return;
  70.   }
  71.  
  72.   foreach my $dvs_pg_view (@$dvs_pg_views) {
  73.     if ($dvs_pg_view->{'config'}->{'defaultPortConfig'}->{'vlan'}->{'vlanId'} == $vlan) {
  74.       if ($my_dvs_pg_view ne '') {
  75.         Util::trace(0, "\nError updating VM '$name': "
  76.                  . "VLAN ID $vlan is not unique!\n");
  77.         return;
  78.       }
  79.       $my_dvs_pg_view = $dvs_pg_view;
  80.     }
  81.   }
  82.  
  83.   if ($my_dvs_pg_view eq '') {
  84.     Util::trace(0, "\nError updating VM '$name': "
  85.                  . "VLAN ID $vlan could not be found!\n");
  86.     return;
  87.   }
  88.  
  89.   if ($DEBUG) { print $my_dvs_pg_view->{'name'} . " ($vlan) => " . $my_dvs_pg_view->{'key'} . "\n"; }
  90.  
  91.   my $dvs_view = Vim::get_view(mo_ref => $my_dvs_pg_view->{'config'}->{'distributedVirtualSwitch'});
  92.   print "PortGroup is on switch ". $dvs_view->{'summary'}->{'name'} . " with UUID ". $dvs_view->{'uuid'} . "\n";
  93.  
  94.   # Find the VM by name
  95.   my $vm;
  96.   $vm = Vim::find_entity_view(
  97.                               view_type => 'VirtualMachine',
  98.                               filter => {'name' => $name}
  99.                               );
  100.   if (!$vm) {
  101.     Util::trace(0, "FATAL: Could not find VM named '$name'!\n");
  102.     return;
  103.   } else {
  104.     if ($DEBUG) {
  105.       print "====== Found VM: ";
  106.       print Dumper($vm);
  107.     }
  108.   }
  109.  
  110.   # Get a handle on the first vNIC on the VM
  111.   my $nic = '';
  112.   my $numdevices = scalar @{$vm->{'config'}->{'hardware'}->{'device'}};
  113.   my $i = 0;
  114.   while (($nic eq '') && ($i < $numdevices)) {
  115.     my $device = $vm->{'config'}->{'hardware'}->{'device'}->[$i];
  116.     if ($device->isa("VirtualEthernetCard")) {
  117.       if ($DEBUG) {
  118.         print "====== Found NIC: ";
  119.         print Dumper($device);
  120.       }
  121.       $nic = $device;
  122.     }
  123.     $i++;
  124.   }
  125.  
  126.   my $my_dvs_pg_conn = DistributedVirtualSwitchPortConnection->new(
  127.                   portgroupKey => $my_dvs_pg_view->{'key'},
  128.                   switchUuid => $dvs_view->{'uuid'},
  129.                         );
  130.   my $nic_backing = VirtualEthernetCardDistributedVirtualPortBackingInfo->new( port => $my_dvs_pg_conn );
  131.   $nic->{'backing'} = $nic_backing;
  132.  
  133.   if ($DEBUG) {
  134.     print "################ Data summary\n";
  135.     print "## my_dvs_pg_conn: ";
  136.     print Dumper($my_dvs_pg_conn);
  137.     print "\n";
  138.     print "## nic_backing: ";
  139.     print Dumper($nic_backing);
  140.     print "\n";
  141.     print "## nic: ";
  142.     print Dumper($nic);
  143.     print "\n";
  144.   }
  145.  
  146.  
  147.   my $device_spec = VirtualDeviceConfigSpec->new(device => $nic);
  148.   # $device_spec isa VirtualDeviceConfigSpec data object
  149.   # $device_spec.device isa VirtualDevice
  150.   # VirtualEthernetCard is a subclass of VirtualDevice
  151.   # $device_spec.device.backing isa VirtualDeviceBackingInfo
  152.   # $device_spec.device.key (required) isa xsd:int
  153.   #
  154.  
  155.   if ($DEBUG) {
  156.     print "## device_spec: ";
  157.     print Dumper($device_spec);
  158.     print "\n";
  159.   }
  160.  
  161.   my @device_spec_array = ();
  162.   if ($device_spec) {
  163.     @device_spec_array = ($device_spec);
  164.   } else {
  165.     Util::trace(0, "\nFATAL: Failed to attach to $my_dvs_pg_view->{'name'}\n");
  166.     return;
  167.   }
  168.   my $vm_reconfig_spec = VirtualMachineConfigSpec->new(deviceChange => \@device_spec_array);
  169.  
  170.   if ($DEBUG) {
  171.     print "## vm_reconfig_spec: ";
  172.     print Dumper($vm_reconfig_spec);
  173.     print "\n";
  174.     print "################ END\n";
  175.   }
  176.  
  177.   eval {
  178.     $vm->ReconfigVM( spec => $vm_reconfig_spec );
  179.     Util::trace(0,"\nVirtual machine '" . $vm->name
  180.                 . "' is reconfigured successfully.\n");
  181.   };
  182.   if ($@) {
  183.     Util::trace(0, "\nReconfiguration failed: ");
  184.     if (ref($@) eq 'SoapFault') {
  185.       if (ref($@->detail) eq 'TooManyDevices') {
  186.         Util::trace(0, "\nNumber of virtual devices exceeds "
  187.                      . "the maximum for a given controller.\n");
  188.       }
  189.       elsif (ref($@->detail) eq 'InvalidDeviceSpec') {
  190.         Util::trace(0, "The Device configuration is not valid\n");
  191.         Util::trace(0, "\nFollowing is the detailed error: \n\n$@");
  192.       }
  193.       elsif (ref($@->detail) eq 'FileAlreadyExists') {
  194.         Util::trace(0, "\nOperation failed because file already exists");
  195.       }
  196.       else {
  197.         Util::trace(0, "\n" . $@ . "\n");
  198.       }
  199.     }
  200.     else {
  201.       Util::trace(0, "\n" . $@ . "\n");
  202.     }
  203.   } #if ($@) // VM reconfiguration failed
  204.  
  205.   if ($DEBUG) {
  206.     print "  ## Final VM: \n";
  207.     print Dumper($vm);
  208.   }
  209.  
  210.   return;
  211. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement