/**
* Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
*/
package net.juniper.contrail.vcenter;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.SortedMap;
import java.util.UUID;
import org.apache.log4j.Logger;
import org.apache.commons.net.util.SubnetUtils;
import net.juniper.contrail.api.ApiConnector;
import net.juniper.contrail.api.ApiConnectorFactory;
import net.juniper.contrail.api.ApiPropertyBase;
import net.juniper.contrail.api.ObjectReference;
import net.juniper.contrail.api.types.InstanceIp;
import net.juniper.contrail.api.types.FloatingIp;
import net.juniper.contrail.api.types.MacAddressesType;
import net.juniper.contrail.api.types.NetworkIpam;
import net.juniper.contrail.api.types.SecurityGroup;
import net.juniper.contrail.api.types.PolicyEntriesType;
import net.juniper.contrail.api.types.SubnetType;
import net.juniper.contrail.api.types.VirtualMachine;
import net.juniper.contrail.api.types.VirtualMachineInterface;
import net.juniper.contrail.api.types.VirtualNetwork;
import net.juniper.contrail.api.types.VnSubnetsType;
import net.juniper.contrail.api.types.VnSubnetsType.IpamSubnetType;
import net.juniper.contrail.api.types.Project;
import net.juniper.contrail.api.types.IdPermsType;
import com.google.common.base.Throwables;
import com.google.common.net.InetAddresses;
public class VncDB {
private static final Logger s_logger =
Logger.getLogger(VncDB.class);
protected static final int vrouterApiPort = 9090;
protected final String apiServerAddress;
protected final int apiServerPort;
protected final String username;
protected final String password;
protected final String tenant;
protected final String authtype;
protected final String authurl;
protected volatile ApiConnector apiConnector;
private boolean alive;
private Project vCenterProject;
private NetworkIpam vCenterIpam;
private SecurityGroup vCenterDefSecGrp;
private IdPermsType vCenterIdPerms;
Mode mode;
public static final String VNC_ROOT_DOMAIN = "default-domain";
public static final String VNC_VCENTER_PROJECT = "vCenter";
public static final String VNC_VCENTER_IPAM = "vCenter-ipam";
public static final String VNC_VCENTER_DEFAULT_SG = "default";
public static final String VNC_VCENTER_PLUGIN = "vcenter-plugin";
public static final String VNC_VCENTER_TEST_PROJECT = "vCenter-test";
public static final String VNC_VCENTER_TEST_IPAM = "vCenter-ipam-test";
public VncDB(String apiServerAddress, int apiServerPort, Mode mode) {
this.apiServerAddress = apiServerAddress;
this.apiServerPort = apiServerPort;
this.mode = mode;
if (mode == Mode.VCENTER_ONLY) {
// Create global id-perms object.
vCenterIdPerms = new IdPermsType();
vCenterIdPerms.setCreator("vcenter-plugin");
vCenterIdPerms.setEnable(true);
}
this.username = null;
this.password = null;
this.tenant = null;
this.authtype = null;
this.authurl = null;
}
public VncDB(String apiServerAddress, int apiServerPort,
String username, String password,
String tenant,
String authtype, String authurl, Mode mode) {
this.apiServerAddress = apiServerAddress;
this.apiServerPort = apiServerPort;
this.mode = mode;
if (mode == Mode.VCENTER_ONLY) {
// Create global id-perms object.
vCenterIdPerms = new IdPermsType();
vCenterIdPerms.setCreator("vcenter-plugin");
vCenterIdPerms.setEnable(true);
}
this.username = username;
this.password = password;
this.tenant = tenant;
this.authtype = authtype;
this.authurl = authurl;
}
public void setApiConnector(ApiConnector _apiConnector) {
apiConnector = _apiConnector;
}
public ApiConnector getApiConnector() {
return apiConnector;
}
public String getApiServerAddress() {
return apiServerAddress;
}
public int getApiServerPort() {
return apiServerPort;
}
public IdPermsType getVCenterIdPerms() {
return vCenterIdPerms;
}
public Project getVCenterProject() {
return vCenterProject;
}
public boolean isServerAlive() {
return alive;
}
public boolean isVncApiServerAlive() {
if (apiConnector == null) {
apiConnector = ApiConnectorFactory.build(apiServerAddress,
apiServerPort);
if (mode == Mode.VCENTER_AS_COMPUTE) {
apiConnector.credentials(username, password)
.tenantName(tenant)
.authServer(authtype, authurl);
}
if (apiConnector == null) {
s_logger.error(" failed to create ApiConnector.. retry later");
alive = false;
return false;
}
}
// Read project list as a life check
s_logger.info(" Checking if api-server is alive and kicking..");
try {
@SuppressWarnings("unchecked")
List<Project> projects = (List<Project>) apiConnector.list(Project.class, null);
if (projects == null) {
s_logger.info(" ApiServer not fully awake yet.. retry again..");
alive = false;
return false;
}
} catch (Exception e) {
alive = false;
return false;
}
alive = true;
s_logger.info(" Api-server alive. Got the pulse..");
return true;
}
public boolean Initialize() {
// Check if api-server is alive
if (isVncApiServerAlive() == false) {
return false;
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
return true;
}
// create objects specific to VCENTER_ONLY mode
// Check if Vmware Project exists on VNC. If not, create one.
try {
vCenterProject = (Project) apiConnector.findByFQN(Project.class,
VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_PROJECT);
} catch (Exception e) {
s_logger.error("Exception in find vcenter project: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
if (vCenterProject == null) {
s_logger.info(" vCenter project not present, creating ");
vCenterProject = new Project();
vCenterProject.setName("vCenter");
vCenterProject.setIdPerms(vCenterIdPerms);
try {
if (!apiConnector.create(vCenterProject)) {
s_logger.error("Unable to create project: " + vCenterProject.getName());
return false;
}
} catch (Exception e) {
s_logger.error("Exception in creating vcenter object: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
} else {
s_logger.info(" vCenter project present, continue ");
}
// Check if VMWare vCenter-ipam exists on VNC. If not, create one.
try {
vCenterIpam = (NetworkIpam) apiConnector.findByFQN(NetworkIpam.class,
VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_PROJECT + ":" + VNC_VCENTER_IPAM);
} catch (Exception e) {
s_logger.error("Exception in find network Ipam: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
if (vCenterIpam == null) {
s_logger.info(" vCenter Ipam not present, creating ...");
vCenterIpam = new NetworkIpam();
vCenterIpam.setParent(vCenterProject);
vCenterIpam.setName("vCenter-ipam");
vCenterIpam.setIdPerms(vCenterIdPerms);
try {
if (!apiConnector.create(vCenterIpam)) {
s_logger.error("Unable to create Ipam: " + vCenterIpam.getName());
}
} catch (Exception e) {
s_logger.error("Exception in network Ipam create: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
} else {
s_logger.info(" vCenter Ipam present, continue ");
}
// Check if VMWare vCenter default security-group exists on VNC. If not, create one.
try {
vCenterDefSecGrp = (SecurityGroup) apiConnector.findByFQN(SecurityGroup.class,
VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_PROJECT + ":" + VNC_VCENTER_DEFAULT_SG);
} catch (Exception e) {
s_logger.error("Exception in find sec group: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
if (vCenterDefSecGrp == null) {
s_logger.info(" vCenter default Security-group not present, creating ...");
vCenterDefSecGrp = new SecurityGroup();
vCenterDefSecGrp.setParent(vCenterProject);
vCenterDefSecGrp.setName("default");
vCenterDefSecGrp.setIdPerms(vCenterIdPerms);
PolicyEntriesType sg_rules = new PolicyEntriesType();
PolicyEntriesType.PolicyRuleType ingress_rule =
new PolicyEntriesType.PolicyRuleType(
null,
UUID.randomUUID().toString(),
">",
"any",
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(null, null, VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_PROJECT + ":" + "default", null, null)}),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //src_ports
null, //application
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(null, null, "local", null, null) }),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //dest_ports
null, // action_list
"IPv4"); // ethertype
sg_rules.addPolicyRule(ingress_rule);
PolicyEntriesType.PolicyRuleType egress_rule =
new PolicyEntriesType.PolicyRuleType(
null,
UUID.randomUUID().toString(),
">",
"any",
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(null, null, "local", null, null) }),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //src_ports
null, //application
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(new SubnetType("0.0.0.0", 0), null, null, null, null) }),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //dest_ports
null, // action_list
"IPv4"); // ethertype);
sg_rules.addPolicyRule(egress_rule);
vCenterDefSecGrp.setEntries(sg_rules);
try {
if (!apiConnector.create(vCenterDefSecGrp)) {
s_logger.error("Unable to create defSecGrp: " + vCenterDefSecGrp.getName());
}
} catch (Exception e) {
s_logger.error("Exception : " + e);
String stackTrace = Throwables.getStackTraceAsString(e);
s_logger.error(stackTrace);
return false;
}
} else {
s_logger.info(" vCenter default sec-group present, continue ");
}
return true;
}
public boolean TestInitialize() {
// Check if Vmware Test Project exists on VNC. If not, create one.
try {
vCenterProject = (Project) apiConnector.findByFQN(Project.class,
VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_TEST_PROJECT);
} catch (IOException e) {
return false;
}
if (vCenterProject == null) {
s_logger.info(" vCenter-test project not present, creating ");
vCenterProject = new Project();
vCenterProject.setName("vCenter-test");
try {
if (!apiConnector.create(vCenterProject)) {
s_logger.error("Unable to create project: " + vCenterProject.getName());
return false;
}
} catch (IOException e) {
s_logger.error("Exception : " + e);
String stackTrace = Throwables.getStackTraceAsString(e);
s_logger.error(stackTrace);
return false;
}
} else {
s_logger.info(" vCenter-test project present, continue ");
}
// Check if VMWare vCenter-test ipam exists on VNC. If not, create one.
try {
vCenterIpam = (NetworkIpam) apiConnector.findByFQN(NetworkIpam.class,
VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_PROJECT + ":" + VNC_VCENTER_TEST_IPAM);
} catch (IOException e) {
return false;
}
if (vCenterIpam == null) {
s_logger.info(" vCenter test Ipam not present, creating ...");
vCenterIpam = new NetworkIpam();
vCenterIpam.setParent(vCenterProject);
vCenterIpam.setName("vCenter-ipam-test");
try {
if (!apiConnector.create(vCenterIpam)) {
s_logger.error("Unable to create test Ipam: " + vCenterIpam.getName());
}
} catch (IOException e) {
s_logger.error("Exception in vCenterIpam create : " + e );
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
} else {
s_logger.info(" vCenter test Ipam present, continue ");
}
// Check if VMWare vCenter default security-group exists on VNC. If not, create one.
try {
vCenterDefSecGrp = (SecurityGroup) apiConnector.findByFQN(SecurityGroup.class,
VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_PROJECT + ":" + VNC_VCENTER_DEFAULT_SG);
} catch (Exception e) {
s_logger.error("Exception in default sec group find: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
if (vCenterDefSecGrp == null) {
s_logger.info(" vCenter default Security-group not present, creating ...");
vCenterDefSecGrp = new SecurityGroup();
vCenterDefSecGrp.setParent(vCenterProject);
vCenterDefSecGrp.setName("default");
PolicyEntriesType sg_rules = new PolicyEntriesType();
PolicyEntriesType.PolicyRuleType ingress_rule =
new PolicyEntriesType.PolicyRuleType(
null,
UUID.randomUUID().toString(),
">",
"any",
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(null, null, VNC_ROOT_DOMAIN + ":" + VNC_VCENTER_PROJECT + ":" + "default", null, null)}),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //src_ports
null, //application
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(null, null, "local", null, null) }),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //dest_ports
null, // action_list
"IPv4"); // ethertype
sg_rules.addPolicyRule(ingress_rule);
PolicyEntriesType.PolicyRuleType egress_rule =
new PolicyEntriesType.PolicyRuleType(
null,
UUID.randomUUID().toString(),
">",
"any",
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(null, null, "local", null, null) }),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //src_ports
null, //application
Arrays.asList(new PolicyEntriesType.PolicyRuleType.AddressType[] {new PolicyEntriesType.PolicyRuleType.AddressType(new SubnetType("0.0.0.0", 0), null, null, null, null) }),
Arrays.asList(new PolicyEntriesType.PolicyRuleType.PortType[] {new PolicyEntriesType.PolicyRuleType.PortType(0,65535)}), //dest_ports
null, // action_list
"IPv4"); // ethertype);
sg_rules.addPolicyRule(egress_rule);
vCenterDefSecGrp.setEntries(sg_rules);
try {
if (!apiConnector.create(vCenterDefSecGrp)) {
s_logger.error("Unable to create def sec grp: " + vCenterDefSecGrp.getName());
}
} catch (Exception e) {
s_logger.error("Exception in default sec group find: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return false;
}
} else {
s_logger.info(" vCenter default sec-group present, continue ");
}
return true;
}
protected static boolean doIgnoreVirtualNetwork(String name) {
// Ignore default, fabric, and link-local networks
if (name.equals("__link_local__") ||
name.equals("default-virtual-network") ||
name.equals("ip-fabric")) {
return true;
}
return false;
}
public void createVirtualNetwork(VirtualNetworkInfo vnInfo)
throws IOException
{
updateVirtualNetwork(vnInfo, true);
}
public void updateVirtualNetwork(VirtualNetworkInfo vnInfo)
throws IOException
{
updateVirtualNetwork(vnInfo, false);
}
private void updateVirtualNetwork(VirtualNetworkInfo vnInfo, boolean create)
throws IOException {
if (vnInfo == null) {
s_logger.error("Cannot create API VN: null arguments");
throw new IllegalArgumentException("Null vnInfo argument");
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
VirtualNetwork vn = new VirtualNetwork();
vn.setUuid(vnInfo.getUuid());
apiConnector.read(vn);
vnInfo.apiVn = vn;
return;
}
VirtualNetwork vn = new VirtualNetwork();
vn.setUuid(vnInfo.getUuid());
if (create) {
// these fields can only be set during create
vn.setName(vnInfo.getName());
vn.setDisplayName(vnInfo.getName());
vn.setIdPerms(vCenterIdPerms);
vn.setParent(vCenterProject);
}
vn.setExternalIpam(vnInfo.getExternalIpam());
VnSubnetsType subnet = getSubnet(vnInfo);
if (subnet != null) {
vn.setNetworkIpam(vCenterIpam, subnet);
}
if (create) {
s_logger.info("Creating API " + vnInfo);
apiConnector.create(vn);
} else {
s_logger.info("Updating API " + vnInfo);
apiConnector.update(vn);
}
apiConnector.read(vn);
vnInfo.apiVn = vn;
}
private VnSubnetsType getSubnet(VirtualNetworkInfo vnInfo) {
if (vnInfo.getSubnetAddress() == null || vnInfo.getSubnetMask() == null) {
return null;
}
SubnetUtils subnetUtils = new SubnetUtils(vnInfo.getSubnetAddress(), vnInfo.getSubnetMask());
String cidr = subnetUtils.getInfo().getCidrSignature();
String[] addr_pair = cidr.split("\\/");
List<VnSubnetsType.IpamSubnetType.AllocationPoolType> allocation_pools = null;
if (vnInfo.getIpPoolEnabled() == true && !vnInfo.getRange().isEmpty()) {
String[] pools = vnInfo.getRange().split("\\#");
if (pools.length == 2) {
allocation_pools = new ArrayList<VnSubnetsType.IpamSubnetType.AllocationPoolType>();
String start = (pools[0]).replace(" ","");
String num = (pools[1]).replace(" ","");
int start_ip = InetAddresses.coerceToInteger(InetAddresses.forString(start));
int end_ip = start_ip + Integer.parseInt(num) - 1;
String end = InetAddresses.toAddrString(InetAddresses.fromInteger(end_ip));
s_logger.debug("Subnet IP Range : Start:" + start + " End:" + end);
VnSubnetsType.IpamSubnetType.AllocationPoolType pool1 = new
VnSubnetsType.IpamSubnetType.AllocationPoolType(start, end);
allocation_pools.add(pool1);
}
}
// if gateway address is empty string, don't pass empty string to
// api-server. INstead set it to null so that java binding will
// drop gateway address from json content for virtual-network create
if (vnInfo.getGatewayAddress() != null) {
if (vnInfo.getGatewayAddress().trim().isEmpty())
vnInfo.setGatewayAddress(null);
}
VnSubnetsType subnet = new VnSubnetsType();
subnet.addIpamSubnets(new VnSubnetsType.IpamSubnetType(
new SubnetType(addr_pair[0],
Integer.parseInt(addr_pair[1])),
vnInfo.getGatewayAddress(),
null, // dns_server_address
UUID.randomUUID().toString(), // subnet_uuid
true, // enable_dhcp
null, // dns_nameservers
allocation_pools,
true, // addr_from_start
null, // dhcp_options_list
null, // host_routes
vnInfo.getName() + "-subnet", 1));
return subnet;
}
public void deleteVirtualNetwork(VirtualNetworkInfo vnInfo)
throws IOException {
if (vnInfo == null) {
s_logger.error("Cannot delete API VN: null arguments");
throw new IllegalArgumentException("Null vnInfo argument");
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
return;
}
VirtualNetwork apiVn = (VirtualNetwork) apiConnector.findById(
VirtualNetwork.class, vnInfo.getUuid());
if (apiVn == null) {
s_logger.error("Cannot delete, not found: " + vnInfo);
return;
}
deleteInstanceIps(apiVn);
deleteVirtualMachineInterfaces(apiVn);
apiConnector.delete(apiVn);
vnInfo.apiVn = null;
s_logger.info("Deleted " + vnInfo);
}
public void createVirtualMachine(VirtualMachineInfo vmInfo)
throws IOException {
if (vmInfo == null) {
s_logger.error("Cannot create API VM: null arguments");
throw new IllegalArgumentException("Null vmInfo argument");
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
return;
}
String vmUuid = vmInfo.getUuid();
VirtualMachine vm = new VirtualMachine();
vmInfo.apiVm = vm;
vm.setName(vmUuid);
vm.setUuid(vmUuid);
// Encode VRouter IP address in display name
if (vmInfo.getVrouterIpAddress() != null) {
vm.setDisplayName(vmInfo.getVrouterIpAddress());
}
vm.setIdPerms(vCenterIdPerms);
apiConnector.create(vm);
s_logger.info("Created " + vm);
}
public void deleteVirtualMachine(VirtualMachineInfo vmInfo)
throws IOException {
if (vmInfo == null) {
s_logger.error("Cannot delete VM: null arguments");
throw new IllegalArgumentException("Null vmInfo argument");
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
return;
}
VirtualMachine apiVm = (VirtualMachine) apiConnector.findById(
VirtualMachine.class, vmInfo.getUuid());
if (apiVm == null) {
s_logger.error("Cannot delete VM, it does not exist in the API server "
+ vmInfo);
return;
}
deleteVirtualMachineInterfaces(apiVm);
apiConnector.delete(apiVm);
vmInfo.apiVm = null;
s_logger.info("Deleted " + vmInfo);
}
public void createVirtualMachineInterface(
VirtualMachineInterfaceInfo vmiInfo)
throws IOException {
if (vmiInfo == null) {
s_logger.error("Cannot create API VMI: null arguments");
throw new IllegalArgumentException("Null vmiInfo argument");
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
return;
}
VirtualMachineInfo vmInfo = vmiInfo.vmInfo;
VirtualNetworkInfo vnInfo = vmiInfo.vnInfo;
VirtualMachine vm = vmInfo.apiVm;
if (vm == null) {
vm = vmInfo.apiVm = (VirtualMachine) apiConnector.findById(
VirtualMachine.class, vmInfo.getUuid());
if (vm == null) {
s_logger.error("Cannot find " + vmInfo);
return;
}
}
VirtualNetwork network = vnInfo.apiVn;
if (network == null) {
network = (VirtualNetwork) apiConnector.findById(
VirtualNetwork.class, vnInfo.getUuid());
if (network == null) {
s_logger.error("Cannot find " + vnInfo);
return;
}
vnInfo.apiVn = network;
}
if (vmiInfo.apiVmi != null) {
return;
}
VirtualMachineInterface apiVmi = readVirtualMachineInterface(vmiInfo);
if (apiVmi != null) {
return;
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
s_logger.error("VMI not found in the API server " + vmiInfo);
return;
}
// create Virtual machine interface
String vmInterfaceName = "vmi-" + vnInfo.getName()
+ "-" + vmInfo.getName();
VirtualMachineInterface vmInterface = new VirtualMachineInterface();
vmInterface.setDisplayName(vmInterfaceName);
if (vmiInfo.getUuid() == null) {
vmiInfo.setUuid(UUID.randomUUID().toString());
}
vmInterface.setUuid(vmiInfo.getUuid());
vmInterface.setName(vmiInfo.getUuid());
vmInterface.setParent(vCenterProject);
vmInterface.setSecurityGroup(vCenterDefSecGrp);
vmInterface.setVirtualNetwork(network);
vmInterface.addVirtualMachine(vm);
MacAddressesType macAddrType = new MacAddressesType();
macAddrType.addMacAddress(vmiInfo.getMacAddress());
vmInterface.setMacAddresses(macAddrType);
vmInterface.setIdPerms(vCenterIdPerms);
apiConnector.create(vmInterface);
apiConnector.read(vmInterface);
vmiInfo.apiVmi = vmInterface;
s_logger.debug("Created " + vmiInfo);
}
public void deleteVirtualMachineInterface(
VirtualMachineInterfaceInfo vmiInfo)
throws IOException {
if (vmiInfo == null) {
s_logger.error("Cannot delete API VMI: null arguments");
throw new IllegalArgumentException("Null vmiInfo argument");
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
return;
}
VirtualMachineInterface apiVmi = (VirtualMachineInterface) apiConnector.findById(
VirtualMachineInterface.class, vmiInfo.getUuid());
if (apiVmi == null) {
s_logger.error("Cannot delete VMI, it does not exist " + vmiInfo);
return;
}
clearSecurityGroups(apiVmi);
clearFloatingIp(apiVmi);
deleteInstanceIps(apiVmi);
apiConnector.delete(apiVmi);
vmiInfo.apiVmi = null;
s_logger.info("Deleted " + vmiInfo);
}
private void clearFloatingIp(VirtualMachineInterface apiVmi) throws IOException {
// Clear floating-ip associations if it exists on VMInterface
List<ObjectReference<ApiPropertyBase>> floatingIpRefs =
apiVmi.getFloatingIpBackRefs();
if ((floatingIpRefs != null) && !floatingIpRefs.isEmpty()) {
s_logger.info("floatingIp association exists for VMInterface:" + apiVmi.getUuid());
// there can be one floating-ip per VMI.
FloatingIp floatingIp = (FloatingIp)
apiConnector.findById(FloatingIp.class,
floatingIpRefs.get(0).getUuid());
// clear VMInterface back reference.
FloatingIp fip = new FloatingIp();
fip.setParent(floatingIp.getParent());
fip.setName(floatingIp.getName());
fip.setUuid(floatingIp.getUuid());
fip.setVirtualMachineInterface(apiVmi);
fip.clearVirtualMachineInterface();
apiConnector.update(fip);
floatingIp.clearVirtualMachineInterface();
s_logger.info("Removed floatingIp association for VMInterface:" + apiVmi.getUuid());
}
}
private void clearSecurityGroups(VirtualMachineInterface apiVmi) throws IOException {
// Clear security-group associations if it exists on VMInterface
List<ObjectReference<ApiPropertyBase>> secGroupRefs =
apiVmi.getSecurityGroup();
if ((secGroupRefs != null) && !secGroupRefs.isEmpty()) {
s_logger.info("SecurityGroup association exists for VMInterface:" + apiVmi.getUuid());
SecurityGroup secGroup = (SecurityGroup)
apiConnector.findById(SecurityGroup.class,
secGroupRefs.get(0).getUuid());
VirtualMachineInterface vmi = new VirtualMachineInterface();
vmi.setParent(apiVmi.getParent());
vmi.setName(apiVmi.getName());
vmi.setUuid(apiVmi.getUuid());
if (secGroup != null) {
vmi.addSecurityGroup(secGroup);
}
vmi.clearSecurityGroup();
apiConnector.update(vmi);
apiVmi.clearSecurityGroup();
s_logger.info("Removed SecurityGroup association for VMInterface:" + apiVmi.getUuid());
}
}
public void createInstanceIp(VirtualMachineInterfaceInfo vmiInfo)
throws IOException {
if (vmiInfo == null) {
s_logger.error("Cannot create API Instance IP: null arguments");
throw new IllegalArgumentException("Null vmiInfo argument");
}
if (mode == Mode.VCENTER_AS_COMPUTE) {
return;
}
VirtualNetwork network = vmiInfo.vnInfo.apiVn;
if (vmiInfo.vnInfo.getSubnetAddress() == null
|| vmiInfo.vnInfo.getSubnetMask() == null) {
return;
}
VirtualMachine vm = vmiInfo.vmInfo.apiVm;
if (vm == null) {
vm = vmiInfo.vmInfo.apiVm = (VirtualMachine) apiConnector.findById(
VirtualMachine.class, vmiInfo.vmInfo.getUuid());
if (vm == null) {
s_logger.error("Cannot find " + vmiInfo);
return;
}
}
VirtualMachineInterface vmIntf = vmiInfo.apiVmi;
String instanceIpName = "ip-" + network.getName() + "-" + vmiInfo.vmInfo.getName() ;
String instIpUuid = UUID.randomUUID().toString();
InstanceIp instanceIp = new InstanceIp();
if (vmiInfo.getIpAddress() != null) {
instanceIp.setAddress(vmiInfo.getIpAddress());
if (vmiInfo.vnInfo.getExternalIpam() == false) {
s_logger.error("Internal error address already set for DHCP");
}
}
instanceIp.setDisplayName(instanceIpName);
instanceIp.setUuid(instIpUuid);
instanceIp.setName(instIpUuid);
instanceIp.setVirtualNetwork(network);
instanceIp.setVirtualMachineInterface(vmIntf);
instanceIp.setIdPerms(vCenterIdPerms);
apiConnector.create(instanceIp);
apiConnector.read(instanceIp);
vmiInfo.apiInstanceIp = instanceIp;
vmiInfo.setIpAddress(instanceIp.getAddress());
s_logger.debug("Created instanceIP: " + instanceIp.getName() + ": " +
instanceIp.getAddress());
}
@SuppressWarnings("unchecked")
SortedMap<String, VirtualNetworkInfo> readVirtualNetworks() {
s_logger.info("Start reading virtual networks from the API server ...");
SortedMap<String, VirtualNetworkInfo> map =
new ConcurrentSkipListMap<String, VirtualNetworkInfo>();
List<VirtualNetwork> apiObjs = null;
try {
apiObjs = (List<VirtualNetwork>)
apiConnector.list(VirtualNetwork.class, null);
} catch (Exception e) {
s_logger.error("Exception in api.list(VirtualNetworks): " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return map;
}
for (VirtualNetwork vn : apiObjs) {
try {
apiConnector.read(vn);
// Ignore network ?
if (doIgnoreVirtualNetwork(vn.getName())) {
continue;
}
// Ignore objects where creator isn't "vcenter-plugin"
if ((mode == Mode.VCENTER_ONLY) &&
((vn.getIdPerms().getCreator() == null) ||
!(vn.getIdPerms().getCreator().equals(VNC_VCENTER_PLUGIN)))) {
continue;
}
VirtualNetworkInfo vnInfo = new VirtualNetworkInfo(vn);
map.put(vnInfo.getUuid(), vnInfo);
} catch (Exception e) {
s_logger.error("Cannot read VN " + vn.getName());
}
}
s_logger.info("Done reading from the API server, found " + map.size() + " Virtual Networks");
return map;
}
public VirtualNetwork findVirtualNetwork(String uuid)
throws IOException {
return (VirtualNetwork) apiConnector.findById(
VirtualNetwork.class, uuid);
}
@SuppressWarnings("unchecked")
SortedMap<String, VirtualMachineInfo> readVirtualMachines() {
s_logger.info("Start reading virtual machines from the API server ...");
List<VirtualMachine> apiVms = null;
SortedMap<String, VirtualMachineInfo> map =
new ConcurrentSkipListMap<String, VirtualMachineInfo>();
try {
apiVms = (List<VirtualMachine>)
apiConnector.list(VirtualMachine.class, null);
} catch (Exception e) {
s_logger.error("Exception in api.list(VirtualMachine): " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return map;
}
for (VirtualMachine vm : apiVms) {
try {
//TODO can we get rid of this call by reading everything with the list?
apiConnector.read(vm);
// Ignore objects where creator isn't "vcenter-plugin"
if ((mode == Mode.VCENTER_ONLY) &&
((vm.getIdPerms().getCreator() == null) ||
!(vm.getIdPerms().getCreator().equals(VNC_VCENTER_PLUGIN)))) {
continue;
}
VirtualMachineInfo vmInfo = new VirtualMachineInfo(vm);
readVirtualMachineInterfaces(vmInfo);
map.put(vmInfo.getUuid(), vmInfo);
} catch (Exception e) {
s_logger.error("Cannot sync VM " + vm.getName());
}
}
s_logger.info("Done reading from the API server, found " + map.size() + " Virtual Machines");
return map;
}
public void readVirtualMachineInterfaces(VirtualMachineInfo vmInfo)
throws IOException {
VirtualMachine vm = vmInfo.apiVm;
if (vm == null) {
vm = vmInfo.apiVm = (VirtualMachine) apiConnector.findById(
VirtualMachine.class, vmInfo.getUuid());
if (vm == null) {
s_logger.error("Cannot find " + vmInfo);
return;
}
}
List<ObjectReference<ApiPropertyBase>> vmInterfaceRefs =
vm.getVirtualMachineInterfaceBackRefs();
for (ObjectReference<ApiPropertyBase> vmInterfaceRef :
Utils.safe(vmInterfaceRefs)) {
String vmInterfaceUuid = vmInterfaceRef.getUuid();
VirtualMachineInterface vmInterface = (VirtualMachineInterface)
apiConnector.findById(VirtualMachineInterface.class,
vmInterfaceUuid);
apiConnector.read(vmInterface);
List<ObjectReference<ApiPropertyBase>> vnRefs =
vmInterface.getVirtualNetwork();
for (ObjectReference<ApiPropertyBase> vnRef : vnRefs) {
VirtualNetworkInfo vnInfo = MainDB.getVnById(vnRef.getUuid());
if (vnInfo == null) {
s_logger.info("Reading from the API server, skipping VMI in unmanaged network "
+ vnRef.getUuid());
continue;
}
VirtualMachineInterfaceInfo vmiInfo =
new VirtualMachineInterfaceInfo(vmInfo, vnInfo);
vmiInfo.apiVmi = vmInterface;
vmiInfo.setUuid(vmInterfaceUuid);
readMacAddress(vmiInfo);
readInstanceIp(vmiInfo);
vmInfo.created(vmiInfo);
}
}
}
private void readMacAddress(VirtualMachineInterfaceInfo vmiInfo)
throws IOException {
VirtualMachineInterface apiVmi = vmiInfo.apiVmi;
if (apiVmi == null) {
apiVmi = (VirtualMachineInterface) apiConnector.findById(
VirtualMachineInterface.class, vmiInfo.getUuid());
if (apiVmi == null) {
return;
}
vmiInfo.apiVmi = apiVmi;
}
List<String> macAddresses = apiVmi.getMacAddresses().getMacAddress();
if (macAddresses.size() > 0) {
vmiInfo.setMacAddress(macAddresses.get(0));
}
}
private void readInstanceIp(VirtualMachineInterfaceInfo vmiInfo)
throws IOException {
VirtualMachineInterface apiVmi =
(VirtualMachineInterface) apiConnector.findById(
VirtualMachineInterface.class, vmiInfo.getUuid());
if (apiVmi == null) {
return;
}
vmiInfo.apiVmi = apiVmi;
List<ObjectReference<ApiPropertyBase>> instanceIpRefs =
apiVmi.getInstanceIpBackRefs();
for (ObjectReference<ApiPropertyBase> instanceIpRef :
Utils.safe(instanceIpRefs)) {
InstanceIp inst = (InstanceIp)
apiConnector.findById(InstanceIp.class,
instanceIpRef.getUuid());
if (inst != null) {
List<ObjectReference<ApiPropertyBase>> vnRefs = inst.getVirtualNetwork();
for (ObjectReference<ApiPropertyBase> vnRef :
Utils.safe(vnRefs)) {
if (vnRef.getUuid().equals(vmiInfo.vnInfo.getUuid())) {
String ipAddress = inst.getAddress();
InetAddress ipAddr = InetAddress.getByName(ipAddress);
if (ipAddr instanceof Inet4Address) {
vmiInfo.setIpAddress(inst.getAddress());
vmiInfo.apiInstanceIp = inst;
// the VMI can have multiple IPv4 and IPv6 addresses,
// but we pick only the first IPv4 address
return;
}
}
}
}
}
}
public VirtualMachineInterface readVirtualMachineInterface(
VirtualMachineInterfaceInfo vmiInfo) throws IOException {
if (vmiInfo == null) {
return null;
}
vmiInfo.vmInfo.apiVm = (VirtualMachine) apiConnector.findById(
VirtualMachine.class, vmiInfo.vmInfo.getUuid());
if (vmiInfo.vmInfo.apiVm == null) {
return null;
}
// find VMI matching vmUuid & vnUuid & macAddress
List<ObjectReference<ApiPropertyBase>> vmInterfaceRefs =
vmiInfo.vmInfo.apiVm.getVirtualMachineInterfaceBackRefs();
for (ObjectReference<ApiPropertyBase> vmInterfaceRef :
Utils.safe(vmInterfaceRefs)) {
String vmInterfaceUuid = vmInterfaceRef.getUuid();
VirtualMachineInterface vmInterface = (VirtualMachineInterface)
apiConnector.findById(VirtualMachineInterface.class,
vmInterfaceUuid);
if (vmInterface == null) {
// back refs may be stale
continue;
}
List<String> macAddresses = vmInterface.getMacAddresses().getMacAddress();
if (macAddresses.size() <= 0) {
continue;
}
if (vmiInfo.getMacAddress() != null
&& !macAddresses.get(0).equals(vmiInfo.getMacAddress())) {
continue;
}
List<ObjectReference<ApiPropertyBase>> vnRefs =
vmInterface.getVirtualNetwork();
for (ObjectReference<ApiPropertyBase> vnRef : vnRefs) {
if (vnRef.getUuid().equals(vmiInfo.vnInfo.getUuid())) {
vmiInfo.apiVmi = vmInterface;
vmiInfo.setUuid(vmInterface.getUuid());
if (vmiInfo.getMacAddress() == null) {
vmiInfo.setMacAddress(macAddresses.get(0));
}
readInstanceIp(vmiInfo);
return vmInterface;
}
}
}
return null;
}
@SuppressWarnings("unchecked")
public void deleteInstanceIps()
throws IOException {
List<InstanceIp> apiObjs = null;
try {
apiObjs = (List<InstanceIp>)
apiConnector.list(InstanceIp.class, null);
} catch (Exception e) {
s_logger.error("Exception in api.list: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return ;
}
for (InstanceIp vn : apiObjs) {
apiConnector.delete(vn);
}
}
public void deleteInstanceIp(VirtualMachineInterfaceInfo vmiInfo)
throws IOException {
if (mode == Mode.VCENTER_AS_COMPUTE) {
return;
}
if (vmiInfo == null) {
s_logger.info("Null argument");
return;
}
VirtualMachineInterface apiVmi = (VirtualMachineInterface) apiConnector.findById(
VirtualMachineInterface.class, vmiInfo.getUuid());
if (apiVmi == null) {
return;
}
vmiInfo.apiVmi = apiVmi;
deleteInstanceIp(apiVmi);
vmiInfo.apiInstanceIp = null;
}
public void deleteInstanceIp(VirtualMachineInterface apiVmi) throws IOException {
// delete instance Ip
List<ObjectReference<ApiPropertyBase>> instanceIpRefs =
apiVmi.getInstanceIpBackRefs();
if (instanceIpRefs == null) {
return;
}
for (ObjectReference<ApiPropertyBase> instanceIpRef :
Utils.safe(instanceIpRefs)) {
s_logger.info("Delete instance IP: " +
instanceIpRef.getReferredName());
apiConnector.delete(InstanceIp.class,
instanceIpRef.getUuid());
s_logger.info("Deleted Ip Instance " + instanceIpRef.getUuid());
}
}
public void deleteInstanceIps(VirtualNetwork apiVn)
throws IOException {
// delete all instance Ip back refs, if there are any left
List<ObjectReference<ApiPropertyBase>> instanceIpRefs =
apiVn.getInstanceIpBackRefs();
if (instanceIpRefs == null) {
return;
}
for (ObjectReference<ApiPropertyBase> instanceIpRef :
Utils.safe(instanceIpRefs)) {
s_logger.info("Delete instance IP: " +
instanceIpRef.getReferredName());
apiConnector.delete(InstanceIp.class,
instanceIpRef.getUuid());
s_logger.info("Deleted Ip Instance " + instanceIpRef.getUuid());
}
}
public void deleteInstanceIps(VirtualMachineInterface apiVmi)
throws IOException {
// delete all instance Ip back refs, if there are any left
List<ObjectReference<ApiPropertyBase>> instanceIpRefs =
apiVmi.getInstanceIpBackRefs();
if (instanceIpRefs == null) {
return;
}
for (ObjectReference<ApiPropertyBase> instanceIpRef :
Utils.safe(instanceIpRefs)) {
s_logger.info("Delete instance IP: " +
instanceIpRef.getReferredName());
apiConnector.delete(InstanceIp.class,
instanceIpRef.getUuid());
s_logger.info("Deleted Ip Instance " + instanceIpRef.getUuid());
}
}
@SuppressWarnings("unchecked")
public void deleteVirtualMachineInterfaces()
throws IOException {
List<VirtualMachineInterface> apiObjs = null;
try {
apiObjs = (List<VirtualMachineInterface>)
apiConnector.list(VirtualMachineInterface.class, null);
} catch (Exception e) {
s_logger.error("Exception in api.list: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return ;
}
for (VirtualMachineInterface vmInterface : apiObjs) {
deleteInstanceIps(vmInterface);
apiConnector.delete(vmInterface);
}
}
public void deleteVirtualMachineInterfaces(VirtualNetwork apiVn)
throws IOException {
// delete all VMIs back refs, if there are any left
List<ObjectReference<ApiPropertyBase>> vmiRefs =
apiVn.getVirtualMachineInterfaceBackRefs();
for (ObjectReference<ApiPropertyBase> vmiRef :
Utils.safe(vmiRefs)) {
VirtualMachineInterface apiVmi =
(VirtualMachineInterface) apiConnector.findById(
VirtualMachineInterface.class, vmiRef.getUuid());
if (apiVmi == null) {
s_logger.error("Cannot delete VMI, it does not exist in the API server "
+ vmiRef.getUuid());
continue;
}
deleteInstanceIps(apiVmi);
s_logger.info("Delete Virtual Machine Interface: " +
vmiRef.getReferredName());
apiConnector.delete(VirtualMachineInterface.class,
vmiRef.getUuid());
s_logger.info("Deleted Virtual Machine Interface "
+ vmiRef.getUuid());
}
}
public void deleteVirtualMachineInterfaces(VirtualMachine apiVm)
throws IOException {
// delete all VMIs back refs, if there are any left
List<ObjectReference<ApiPropertyBase>> vmiRefs =
apiVm.getVirtualMachineInterfaceBackRefs();
for (ObjectReference<ApiPropertyBase> vmiRef :
Utils.safe(vmiRefs)) {
VirtualMachineInterface apiVmi =
(VirtualMachineInterface) apiConnector.findById(
VirtualMachineInterface.class, vmiRef.getUuid());
if (apiVmi == null) {
s_logger.error("Cannot delete VMI, it does not exist in the API server "
+ vmiRef.getUuid());
continue;
}
deleteInstanceIps(apiVmi);
s_logger.info("Delete Virtual Machine Interface: " +
vmiRef.getReferredName());
apiConnector.delete(VirtualMachineInterface.class,
vmiRef.getUuid());
s_logger.info("Deleted Virtual Machine Interface "
+ vmiRef.getUuid());
}
}
@SuppressWarnings("unchecked")
public void deleteVirtualMachines()
throws IOException {
List<VirtualMachine> apiObjs = null;
try {
apiObjs = (List<VirtualMachine>)
apiConnector.list(VirtualMachine.class, null);
} catch (Exception e) {
s_logger.error("Exception in api.list: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return ;
}
for (VirtualMachine vm : apiObjs) {
apiConnector.delete(vm);
}
}
@SuppressWarnings("unchecked")
public void deleteVirtualNetworks()
throws IOException {
List<VirtualNetwork> apiObjs = null;
try {
apiObjs = (List<VirtualNetwork>)
apiConnector.list(VirtualNetwork.class, null);
} catch (Exception e) {
s_logger.error("Exception in api.list: " + e);
s_logger.error(Throwables.getStackTraceAsString(e));
return ;
}
for (VirtualNetwork vn : apiObjs) {
apiConnector.delete(vn);
}
}
public void deleteAll() {
try {
deleteInstanceIps();
deleteVirtualMachineInterfaces();
deleteVirtualMachines();
deleteVirtualNetworks();
} catch (Exception e) {
s_logger.error(Throwables.getStackTraceAsString(e));
}
}
}