/******************************************************************************* * Copyright 2012 Urbancode, Inc * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.urbancode.terraform.tasks.vmware; import java.rmi.RemoteException; import java.util.UUID; import org.apache.log4j.Logger; import com.urbancode.terraform.tasks.vmware.util.Path; import com.urbancode.terraform.tasks.vmware.util.SwitchResult; import com.urbancode.terraform.tasks.vmware.util.VirtualHost; import com.urbancode.x2o.tasks.Restorable; import com.urbancode.x2o.tasks.SubTask; import com.vmware.vim25.HostNetworkPolicy; import com.vmware.vim25.HostPortGroupSpec; import com.vmware.vim25.HostVirtualSwitchSpec; import com.vmware.vim25.mo.ComputeResource; import com.vmware.vim25.mo.HostNetworkSystem; import com.vmware.vim25.mo.HostSystem; import com.vmware.vim25.mo.Network; public class NetworkTask extends SubTask implements Restorable { //********************************************************************************************** // CLASS //********************************************************************************************** static private final Logger log = Logger.getLogger(NetworkTask.class); //********************************************************************************************** // INSTANCE //********************************************************************************************** private String networkName; private String switchName; private String portGroupName; private int portCount; private int vlanId = 0; private SwitchResult vSwitch; private VirtualHost host = null; private Path hostPath = null; //---------------------------------------------------------------------------------------------- public NetworkTask() { super(); } //---------------------------------------------------------------------------------------------- public String getNetworkName() { return this.networkName; } //---------------------------------------------------------------------------------------------- public int getPortCount() { return this.portCount; } //---------------------------------------------------------------------------------------------- public String getSwitchName() { return this.switchName; } //---------------------------------------------------------------------------------------------- public String getPortGroupName() { return this.portGroupName; } //---------------------------------------------------------------------------------------------- public int getVlanId() { return vlanId; } //---------------------------------------------------------------------------------------------- public SwitchResult fetchSwitch() { return this.vSwitch; } //---------------------------------------------------------------------------------------------- public void setHostPath(Path hostPath) { this.hostPath = hostPath; } //---------------------------------------------------------------------------------------------- public void setVirtualHost(VirtualHost host) { this.host = host; } //---------------------------------------------------------------------------------------------- public void setNetworkName(String networkName) { this.networkName = networkName; } //---------------------------------------------------------------------------------------------- public void setPortCount(int portCount) { this.portCount = portCount; } //---------------------------------------------------------------------------------------------- public void setSwitchName(String switchName) { this.switchName = switchName; } //---------------------------------------------------------------------------------------------- public void setPortGroupName(String portGroupName) { this.portGroupName = portGroupName; } //---------------------------------------------------------------------------------------------- public void setSwitch(SwitchResult vSwitch) { this.vSwitch = vSwitch; } //---------------------------------------------------------------------------------------------- public void setVlanId(int vlanId) { this.vlanId = vlanId; } //---------------------------------------------------------------------------------------------- /** * Creates a virtual switch and port group. * The virtual switch has a randomly generated name of 10 hexadecimal characters. * The port group has the same name as the virtual switch with the suffix "-network" appended. * @return a SwitchResult object storing the VI Java Network object and paths to the port group and virtual switch * @throws RemoteException */ private SwitchResult createSwitch() throws RemoteException { String newSwitchName = UUID.randomUUID().toString().replaceAll("-", ""); if (newSwitchName.length() > 10) { newSwitchName = newSwitchName.substring(0, 10); } SwitchResult result; log.debug("Host path: " + hostPath); log.debug("Host: " + host); ComputeResource res = host.getComputeResource(hostPath); HostSystem hostSys = res.getHosts()[0]; HostNetworkSystem networkSystem = hostSys.getHostNetworkSystem(); HostVirtualSwitchSpec switchSpec = new HostVirtualSwitchSpec(); switchSpec.setNumPorts(portCount); networkSystem.addVirtualSwitch(newSwitchName, switchSpec); String newPortGroupName = newSwitchName + "-network"; HostPortGroupSpec portGroupSpec = new HostPortGroupSpec(); portGroupSpec.setName(newPortGroupName); portGroupSpec.setVswitchName(newSwitchName); portGroupSpec.setVlanId(vlanId); portGroupSpec.setPolicy(new HostNetworkPolicy()); networkSystem.addPortGroup(portGroupSpec); Network network = null; for (Network n : hostSys.getNetworks()) { if (n.getName().equals(newPortGroupName)) { network = n; break; } } if (network == null) { throw new RemoteException("Network created but not found"); } Path switchPath = new Path(hostPath, newSwitchName); Path portGroupPath = new Path(hostPath, newPortGroupName); result = new SwitchResult(network, switchPath, portGroupPath); this.switchName = newSwitchName; this.portGroupName = newPortGroupName; return result; } //---------------------------------------------------------------------------------------------- /** * Restores the SwitchResult object for the network task * @param host * @throws RemoteException */ public void restoreNetwork(VirtualHost host) throws RemoteException { ComputeResource res = host.getComputeResource(hostPath); HostSystem hostSys = res.getHosts()[0]; Network network = null; for (Network n : hostSys.getNetworks()) { if (n.getName().equals(portGroupName)) { network = n; break; } } if (network == null) { throw new RemoteException("Could not restore network from xml."); } Path switchPath = new Path(hostPath, switchName); Path portGroupPath = new Path(hostPath, portGroupName); SwitchResult switchResult = new SwitchResult(network, switchPath, portGroupPath); this.vSwitch = switchResult; } //---------------------------------------------------------------------------------------------- @Override public void create() { try { this.vSwitch = createSwitch(); } catch (RemoteException e) { log.warn("RemoteException while creating virtual switch", e); } } //---------------------------------------------------------------------------------------------- @Override public void destroy() { try { restoreNetwork(host); host.removePortGroup(vSwitch.getPortGroupPath()); host.removeSwitch(vSwitch.getSwitchPath()); } catch (RemoteException e) { log.warn("Unable to delete network", e); } } //---------------------------------------------------------------------------------------------- @Override public void restore() { try { restoreNetwork(host); } catch (RemoteException e) { log.warn("Unable to restore network", e); } } }