sub add_ethernet_adapter()

in managementnode/lib/VCL/Module/Provisioning/VMware/vSphere_SDK.pm [4094:4219]


sub add_ethernet_adapter {
	my $self = shift;
	if (ref($self) !~ /VCL::Module/i) {
		notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
		return;
	}
	
	# Get the vmx path argument and convert it to a datastore path
	my $vmx_path = $self->_get_datastore_path(shift) || return;
	
	# Get the adapter spec argument and make sure required values are included
	my $adapter_specification = shift;
	if (!$adapter_specification) {
		notify($ERRORS{'WARNING'}, 0, "adapter specification argument was not supplied");
		return;
	}
	my $adapter_type = $adapter_specification->{adapter_type};
	my $network_name = $adapter_specification->{network_name};
	my $address_type = $adapter_specification->{address_type};
	my $address = $adapter_specification->{address} || '';
	if (!$adapter_type) {
		notify($ERRORS{'WARNING'}, 0, "'adapter_type' is missing from adapter specification:\n" . format_data($adapter_specification));
		return;
	}
	if (!$network_name) {
		notify($ERRORS{'WARNING'}, 0, "'network_name' is missing from adapter specification:\n" . format_data($adapter_specification));
		return;
	}
	if (!$address_type) {
		notify($ERRORS{'WARNING'}, 0, "'address_type' is missing from adapter specification:\n" . format_data($adapter_specification));
		return;
	}
	
	# Get the VM host's network info
	my $host_network_info = $self->get_host_network_info();
	if (!$host_network_info) {
		notify($ERRORS{'WARNING'}, 0, "unable to add ethernet adapter, VM host network info could not be retrieved");
		return;
	}
	
	# Make sure the network name provided in the adapter spec argument was found on the VM host
	my $adapter_network_info = $host_network_info->{$network_name};
	if (!$adapter_network_info) {
		notify($ERRORS{'WARNING'}, 0, "unable to add ethernet adapter, VM host network info does not contain a network named '$network_name'");
		return;
	}
	my $adapter_network_type = $adapter_network_info->{type};
	
	# Assemble the backing info
	my $backing;
	if ($adapter_network_type eq 'DistributedVirtualPortgroup') {
		my $portgroup_key = $adapter_network_info->{portgroupKey};
		my $switch_uuid = $adapter_network_info->{switchUuid};
		
		$backing = VirtualEthernetCardDistributedVirtualPortBackingInfo->new(
			port => DistributedVirtualSwitchPortConnection->new(
				portgroupKey => $portgroup_key,
				switchUuid => $switch_uuid,
			),
		);
	}
	else {
		my $network = $adapter_network_info->{network};
		$backing = VirtualEthernetCardNetworkBackingInfo->new(
			deviceName => $network_name,
			network => $network,
		);
	}
	
	# Assemble the ethernet device
	my $ethernet_device;
	if ($adapter_type =~ /e1000/i) {
		$ethernet_device = VirtualE1000->new(
			key => '',
			backing => $backing,
			addressType => $address_type,
			macAddress => $address,
		);
	}
	elsif ($adapter_type =~ /vmxnet/i) {
		$ethernet_device = VirtualVmxnet3->new(
			key => '',
			backing => $backing,
			addressType => $address_type,
			macAddress => $address,
		);
	}
	else {
		$ethernet_device = VirtualPCNet32->new(
			key => '',
			backing => $backing,
			addressType => $address_type,
			macAddress => $address,
		);
	}
	
	# Assemble the VM config spec
	my $vm_config_spec = VirtualMachineConfigSpec->new(
		deviceChange => [
			VirtualDeviceConfigSpec->new(
				operation =>	VirtualDeviceConfigSpecOperation->new('add'),
				device => $ethernet_device,
			),
		],
	);
	
	# Override the die handler
	local $SIG{__DIE__} = sub{};
	
	my $vm = $self->_get_vm_view($vmx_path) || return;
	
	notify($ERRORS{'DEBUG'}, 0, "attempting to add ethernet adapter to VM: $vmx_path:\n" . format_data($adapter_specification));
	eval {
		$vm->ReconfigVM(
			spec => $vm_config_spec,
		);
	};
	if ($@) {
		notify($ERRORS{'WARNING'}, 0, "failed to add ethernet adapter to VM: $vmx_path, adapter specification:\n" . format_data($adapter_specification) . "\nerror:\n$@");
		return;
	}
	else {
		notify($ERRORS{'DEBUG'}, 0, "added ethernet adapter to VM: $vmx_path:\n" . format_data($adapter_specification));
		return 1;
	}
}