1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.redhat.vmtruckloader.vmware.action;
23
24 import java.rmi.RemoteException;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28
29 import org.redhat.vmtruckloader.vmware.VMWareMachineService;
30 import org.redhat.vmtruckloader.vmware.VMWareManagedObjectUtils;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import com.vmware.vim25.ConcurrentAccess;
35 import com.vmware.vim25.DVPortgroupConfigInfo;
36 import com.vmware.vim25.DistributedVirtualSwitchPortConnection;
37 import com.vmware.vim25.DuplicateName;
38 import com.vmware.vim25.FileFault;
39 import com.vmware.vim25.InsufficientResourcesFault;
40 import com.vmware.vim25.InvalidDatastore;
41 import com.vmware.vim25.InvalidName;
42 import com.vmware.vim25.InvalidState;
43 import com.vmware.vim25.RuntimeFault;
44 import com.vmware.vim25.TaskInProgress;
45 import com.vmware.vim25.VirtualDevice;
46 import com.vmware.vim25.VirtualDeviceBackingInfo;
47 import com.vmware.vim25.VirtualDeviceConfigSpec;
48 import com.vmware.vim25.VirtualDeviceConfigSpecOperation;
49 import com.vmware.vim25.VirtualEthernetCardDistributedVirtualPortBackingInfo;
50 import com.vmware.vim25.VirtualMachineConfigSpec;
51 import com.vmware.vim25.VirtualVmxnet3;
52 import com.vmware.vim25.VmConfigFault;
53 import com.vmware.vim25.mo.DistributedVirtualPortgroup;
54 import com.vmware.vim25.mo.ManagedEntity;
55 import com.vmware.vim25.mo.ServiceInstance;
56 import com.vmware.vim25.mo.VirtualMachine;
57 import com.vmware.vim25.mo.VmwareDistributedVirtualSwitch;
58
59
60
61
62
63 public class MoveVirtualMachineToNetworkCallback extends AbstractVMWareActionCallback<Void> {
64
65 private static final Logger LOGGER = LoggerFactory.getLogger(VMWareMachineService.class);
66
67 private String netName;
68 private String name;
69
70 public MoveVirtualMachineToNetworkCallback(String netName, String name) {
71 super();
72 this.netName = netName;
73 this.name = name;
74 }
75
76 @Override
77 public Void doInVmware(ServiceInstance serviceInstance) {
78 final VirtualMachine vm = checkVmConfigState(VMWareManagedObjectUtils.getVm(serviceInstance, name));
79
80 final String[] virtualPortConfig = findEthernetConfig(serviceInstance, netName);
81 if ( virtualPortConfig.length < 2 )
82 throw new IllegalArgumentException("The netname provided [" + netName + "] is incorrect");
83 final String portGroupKey = virtualPortConfig[0];
84 final String switchUuid = virtualPortConfig[1];
85
86 final VirtualDeviceConfigSpec ethernet = retrieveAndUpdateEthernetPort(vm.getConfig().getHardware().getDevice(),
87 createVirtualPortBackingInfo(portGroupKey,switchUuid));
88 if ( ethernet == null )
89 invalidState("No ethernet found for VM:" + name + ", can't move it to " + netName);
90
91 ethernet.setOperation(VirtualDeviceConfigSpecOperation.edit);
92
93 final VirtualMachineConfigSpec spec = new VirtualMachineConfigSpec();
94 spec.setDeviceChange(new VirtualDeviceConfigSpec[] { ethernet } );
95 reconfigureVM(vm, spec);
96 return null;
97 }
98
99 private static void reconfigureVM(VirtualMachine vm, VirtualMachineConfigSpec spec) {
100 try {
101 vm.reconfigVM_Task(spec);
102 } catch (InvalidName e) {
103 throw new IllegalArgumentException(e);
104 } catch (VmConfigFault e) {
105 throw new IllegalArgumentException(e);
106 } catch (DuplicateName e) {
107 throw new IllegalArgumentException(e);
108 } catch (TaskInProgress e) {
109 throw new IllegalStateException(e);
110 } catch (FileFault e) {
111 throw new IllegalStateException(e);
112 } catch (InvalidState e) {
113 throw new IllegalStateException(e);
114 } catch (ConcurrentAccess e) {
115 throw new IllegalStateException(e);
116 } catch (InvalidDatastore e) {
117 throw new IllegalArgumentException(e);
118 } catch (InsufficientResourcesFault e) {
119 throw new IllegalStateException(e);
120 } catch (RuntimeFault e) {
121 throw new IllegalStateException(e);
122 } catch (RemoteException e) {
123 throw new IllegalStateException(e);
124 }
125 }
126
127 private static VirtualDeviceConfigSpec retrieveAndUpdateEthernetPort(VirtualDevice[] devices, VirtualDeviceBackingInfo netBackingInfo) {
128 VirtualDeviceConfigSpec ethernet = null;
129 for ( VirtualDevice device : devices ) {
130 if ( device instanceof VirtualVmxnet3 ) {
131 final VirtualVmxnet3 xnet3 = (VirtualVmxnet3) device;
132 xnet3.setBacking(netBackingInfo);
133 ethernet = specFromDevice(xnet3);
134 }
135 }
136 return ethernet;
137 }
138
139 private static void invalidState(final String mssg) {
140 LOGGER.warn(mssg);
141 throw new IllegalStateException(mssg);
142 }
143
144 private VirtualMachine checkVmConfigState(VirtualMachine vm) {
145 if ( vm == null || vm.getConfig() == null || vm.getConfig().getHardware() == null || vm.getConfig().getHardware().getDevice() == null) {
146 invalidState("VM " + name + " has no config or hardware infos. Something is wrong, aborting moving the VM to VLAN" + netName);
147 }
148 return vm;
149 }
150
151 private static VirtualEthernetCardDistributedVirtualPortBackingInfo createVirtualPortBackingInfo(String portGroupKey, String switchUuid) {
152 final VirtualEthernetCardDistributedVirtualPortBackingInfo netBacking = new VirtualEthernetCardDistributedVirtualPortBackingInfo();
153 final DistributedVirtualSwitchPortConnection port = new DistributedVirtualSwitchPortConnection();
154 port.setPortgroupKey(portGroupKey);
155 port.setSwitchUuid(switchUuid);
156 netBacking.setPort(port);
157 return netBacking;
158 }
159
160 private static VirtualDeviceConfigSpec specFromDevice(VirtualDevice device) {
161 final VirtualDeviceConfigSpec spec = new VirtualDeviceConfigSpec();
162 spec.setOperation(VirtualDeviceConfigSpecOperation.add);
163 spec.setDevice(device);
164 return spec;
165 }
166
167
168
169
170
171
172
173 private String[] findEthernetConfig(ServiceInstance serviceInstance, String networkName) {
174 String networkNameEncoded = networkName.replaceAll("/", "%2f");
175 System.out.println("NetworkName:" + networkName);
176 Map<String, VmwareDistributedVirtualSwitch> switches = new HashMap<String, VmwareDistributedVirtualSwitch>();
177 List<ManagedEntity> switchList = VMWareManagedObjectUtils.getManagedEntities(serviceInstance,VmwareDistributedVirtualSwitch.class.getSimpleName());
178 for (ManagedEntity me: switchList) {
179 VmwareDistributedVirtualSwitch sw = (VmwareDistributedVirtualSwitch)me;
180 switches.put(sw.getMOR().get_value(), sw);
181 System.out.println("Switch found:" + sw.getName() + "[" + sw.getNetworkResourcePool() + "]");
182 }
183
184 List<ManagedEntity> managedEntities = VMWareManagedObjectUtils.getManagedEntities(serviceInstance,DistributedVirtualPortgroup.class.getSimpleName());
185 for (ManagedEntity me: managedEntities) {
186 DistributedVirtualPortgroup g = (DistributedVirtualPortgroup)me;
187 if (g.getName().equals(networkNameEncoded)) {
188 String switchKey = ((DVPortgroupConfigInfo)g.getConfig()).getDistributedVirtualSwitch().get_value();
189 VmwareDistributedVirtualSwitch sw = switches.get(switchKey);
190 System.out.println("VirtualSwitch found:" + g.getName() + "[" + g.getKey() + "]");
191 return new String[] { g.getKey(), sw.getUuid() };
192 }
193 }
194 return new String[0];
195 }
196
197 }