Search in sources :

Example 31 with Network

use of com.vmware.vim25.mo.Network in project cloudstack by apache.

the class VirtualMachineMO method getNetworksWithDetails.

public List<NetworkDetails> getNetworksWithDetails() throws Exception {
    List<NetworkDetails> networks = new ArrayList<NetworkDetails>();
    int gcTagKey = getCustomFieldKey("Network", CustomFieldConstants.CLOUD_GC);
    if (gcTagKey == 0) {
        gcTagKey = getCustomFieldKey("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
        s_logger.debug("The custom key for dvPortGroup is : " + gcTagKey);
    }
    PropertySpec pSpec = new PropertySpec();
    pSpec.setType("Network");
    pSpec.getPathSet().add("name");
    pSpec.getPathSet().add("vm");
    pSpec.getPathSet().add(String.format("value[%d]", gcTagKey));
    TraversalSpec vm2NetworkTraversal = new TraversalSpec();
    vm2NetworkTraversal.setType("VirtualMachine");
    vm2NetworkTraversal.setPath("network");
    vm2NetworkTraversal.setName("vm2NetworkTraversal");
    ObjectSpec oSpec = new ObjectSpec();
    oSpec.setObj(_mor);
    oSpec.setSkip(Boolean.TRUE);
    oSpec.getSelectSet().add(vm2NetworkTraversal);
    PropertyFilterSpec pfSpec = new PropertyFilterSpec();
    pfSpec.getPropSet().add(pSpec);
    pfSpec.getObjectSet().add(oSpec);
    List<PropertyFilterSpec> pfSpecArr = new ArrayList<PropertyFilterSpec>();
    pfSpecArr.add(pfSpec);
    List<ObjectContent> ocs = _context.getService().retrieveProperties(_context.getPropertyCollector(), pfSpecArr);
    if (ocs != null && ocs.size() > 0) {
        for (ObjectContent oc : ocs) {
            ArrayOfManagedObjectReference morVms = null;
            String gcTagValue = null;
            String name = null;
            for (DynamicProperty prop : oc.getPropSet()) {
                if (prop.getName().equals("name"))
                    name = prop.getVal().toString();
                else if (prop.getName().equals("vm"))
                    morVms = (ArrayOfManagedObjectReference) prop.getVal();
                else if (prop.getName().startsWith("value[")) {
                    CustomFieldStringValue val = (CustomFieldStringValue) prop.getVal();
                    if (val != null)
                        gcTagValue = val.getValue();
                }
            }
            NetworkDetails details = new NetworkDetails(name, oc.getObj(), (morVms != null ? morVms.getManagedObjectReference().toArray(new ManagedObjectReference[morVms.getManagedObjectReference().size()]) : null), gcTagValue);
            networks.add(details);
        }
        s_logger.debug("Retrieved " + networks.size() + " networks with key : " + gcTagKey);
    }
    return networks;
}
Also used : PropertyFilterSpec(com.vmware.vim25.PropertyFilterSpec) DynamicProperty(com.vmware.vim25.DynamicProperty) ArrayList(java.util.ArrayList) ArrayOfManagedObjectReference(com.vmware.vim25.ArrayOfManagedObjectReference) ObjectContent(com.vmware.vim25.ObjectContent) ObjectSpec(com.vmware.vim25.ObjectSpec) PropertySpec(com.vmware.vim25.PropertySpec) TraversalSpec(com.vmware.vim25.TraversalSpec) CustomFieldStringValue(com.vmware.vim25.CustomFieldStringValue) ArrayOfManagedObjectReference(com.vmware.vim25.ArrayOfManagedObjectReference) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Example 32 with Network

use of com.vmware.vim25.mo.Network in project cloudstack by apache.

the class VmwareResource method configure.

@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
    try {
        _name = name;
        _url = (String) params.get("url");
        _username = (String) params.get("username");
        _password = (String) params.get("password");
        _dcId = (String) params.get("zone");
        _pod = (String) params.get("pod");
        _cluster = (String) params.get("cluster");
        _guid = (String) params.get("guid");
        String[] tokens = _guid.split("@");
        _vCenterAddress = tokens[1];
        _morHyperHost = new ManagedObjectReference();
        String[] hostTokens = tokens[0].split(":");
        _morHyperHost.setType(hostTokens[0]);
        _morHyperHost.setValue(hostTokens[1]);
        _guestTrafficInfo = (VmwareTrafficLabel) params.get("guestTrafficInfo");
        _publicTrafficInfo = (VmwareTrafficLabel) params.get("publicTrafficInfo");
        VmwareContext context = getServiceContext();
        VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
        if (mgr == null) {
            throw new ConfigurationException("Invalid vmwareContext:  vmwareMgr stock object is not set or cleared.");
        }
        mgr.setupResourceStartupParams(params);
        CustomFieldsManagerMO cfmMo = new CustomFieldsManagerMO(context, context.getServiceContent().getCustomFieldsManager());
        cfmMo.ensureCustomFieldDef("Datastore", CustomFieldConstants.CLOUD_UUID);
        if (_publicTrafficInfo != null && _publicTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch || _guestTrafficInfo != null && _guestTrafficInfo.getVirtualSwitchType() != VirtualSwitchType.StandardVirtualSwitch) {
            cfmMo.ensureCustomFieldDef("DistributedVirtualPortgroup", CustomFieldConstants.CLOUD_GC_DVP);
        }
        cfmMo.ensureCustomFieldDef("Network", CustomFieldConstants.CLOUD_GC);
        cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_UUID);
        cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_NIC_MASK);
        cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_VM_INTERNAL_NAME);
        cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER);
        cfmMo.ensureCustomFieldDef("VirtualMachine", CustomFieldConstants.CLOUD_WORKER_TAG);
        VmwareHypervisorHost hostMo = this.getHyperHost(context);
        _hostName = hostMo.getHyperHostName();
        if (_guestTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch || _publicTrafficInfo.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) {
            _privateNetworkVSwitchName = mgr.getPrivateVSwitchName(Long.parseLong(_dcId), HypervisorType.VMware);
            _vsmCredentials = mgr.getNexusVSMCredentialsByClusterId(Long.parseLong(_cluster));
        }
        if (_privateNetworkVSwitchName == null) {
            _privateNetworkVSwitchName = (String) params.get("private.network.vswitch.name");
        }
        String value = (String) params.get("vmware.recycle.hung.wokervm");
        if (value != null && value.equalsIgnoreCase("true"))
            _recycleHungWorker = true;
        value = (String) params.get("vmware.root.disk.controller");
        if (value != null && value.equalsIgnoreCase("scsi"))
            _rootDiskController = DiskControllerType.scsi;
        else if (value != null && value.equalsIgnoreCase("ide"))
            _rootDiskController = DiskControllerType.ide;
        else
            _rootDiskController = DiskControllerType.osdefault;
        Integer intObj = (Integer) params.get("ports.per.dvportgroup");
        if (intObj != null)
            _portsPerDvPortGroup = intObj.intValue();
        s_logger.info("VmwareResource network configuration info." + " private traffic over vSwitch: " + _privateNetworkVSwitchName + ", public traffic over " + _publicTrafficInfo.getVirtualSwitchType() + " : " + _publicTrafficInfo.getVirtualSwitchName() + ", guest traffic over " + _guestTrafficInfo.getVirtualSwitchType() + " : " + _guestTrafficInfo.getVirtualSwitchName());
        Boolean boolObj = (Boolean) params.get("vmware.create.full.clone");
        if (boolObj != null && boolObj.booleanValue()) {
            _fullCloneFlag = true;
        } else {
            _fullCloneFlag = false;
        }
        boolObj = (Boolean) params.get("vm.instancename.flag");
        if (boolObj != null && boolObj.booleanValue()) {
            _instanceNameFlag = true;
        } else {
            _instanceNameFlag = false;
        }
        value = (String) params.get("scripts.timeout");
        int timeout = NumbersUtil.parseInt(value, 1440) * 1000;
        storageNfsVersion = NfsSecondaryStorageResource.retrieveNfsVersionFromParams(params);
        _storageProcessor = new VmwareStorageProcessor((VmwareHostService) this, _fullCloneFlag, (VmwareStorageMount) mgr, timeout, this, _shutdownWaitMs, null, storageNfsVersion);
        storageHandler = new VmwareStorageSubsystemCommandHandler(_storageProcessor, storageNfsVersion);
        _vrResource = new VirtualRoutingResource(this);
        if (!_vrResource.configure(name, params)) {
            throw new ConfigurationException("Unable to configure VirtualRoutingResource");
        }
        if (s_logger.isTraceEnabled()) {
            s_logger.trace("Successfully configured VmwareResource.");
        }
        return true;
    } catch (Exception e) {
        s_logger.error("Unexpected Exception ", e);
        throw new ConfigurationException("Failed to configure VmwareResource due to unexpect exception.");
    } finally {
        recycleServiceContext();
    }
}
Also used : VmwareStorageProcessor(com.cloud.storage.resource.VmwareStorageProcessor) VmwareManager(com.cloud.hypervisor.vmware.manager.VmwareManager) VirtualRoutingResource(com.cloud.agent.resource.virtualnetwork.VirtualRoutingResource) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) ConnectException(java.net.ConnectException) IOException(java.io.IOException) RemoteException(java.rmi.RemoteException) InternalErrorException(com.cloud.exception.InternalErrorException) CloudException(com.cloud.exception.CloudException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ConfigurationException(javax.naming.ConfigurationException) CustomFieldsManagerMO(com.cloud.hypervisor.vmware.mo.CustomFieldsManagerMO) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) VmwareStorageSubsystemCommandHandler(com.cloud.storage.resource.VmwareStorageSubsystemCommandHandler) ConfigurationException(javax.naming.ConfigurationException) VmwareHostService(com.cloud.hypervisor.vmware.manager.VmwareHostService) VmwareStorageMount(com.cloud.hypervisor.vmware.manager.VmwareStorageMount) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Example 33 with Network

use of com.vmware.vim25.mo.Network in project cloudstack by apache.

the class VmwareResource method execute.

protected StartAnswer execute(StartCommand cmd) {
    if (s_logger.isInfoEnabled()) {
        s_logger.info("Executing resource StartCommand: " + _gson.toJson(cmd));
    }
    VirtualMachineTO vmSpec = cmd.getVirtualMachine();
    boolean vmAlreadyExistsInVcenter = false;
    String existingVmName = null;
    VirtualMachineFileInfo existingVmFileInfo = null;
    VirtualMachineFileLayoutEx existingVmFileLayout = null;
    Pair<String, String> names = composeVmNames(vmSpec);
    String vmInternalCSName = names.first();
    String vmNameOnVcenter = names.second();
    String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
    String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);
    DiskTO rootDiskTO = null;
    // This helps avoid mix of different scsi subtype controllers in instance.
    if (DiskControllerType.lsilogic == DiskControllerType.getType(rootDiskController)) {
        dataDiskController = DiskControllerType.scsi.toString();
    }
    // Validate the controller types
    dataDiskController = DiskControllerType.getType(dataDiskController).toString();
    rootDiskController = DiskControllerType.getType(rootDiskController).toString();
    if (DiskControllerType.getType(rootDiskController) == DiskControllerType.none) {
        throw new CloudRuntimeException("Invalid root disk controller detected : " + rootDiskController);
    }
    if (DiskControllerType.getType(dataDiskController) == DiskControllerType.none) {
        throw new CloudRuntimeException("Invalid data disk controller detected : " + dataDiskController);
    }
    Pair<String, String> controllerInfo = new Pair<String, String>(rootDiskController, dataDiskController);
    Boolean systemVm = vmSpec.getType().isUsedBySystem();
    // Thus, vmInternalCSName always holds i-x-y, the cloudstack generated internal VM name.
    VmwareContext context = getServiceContext();
    DatacenterMO dcMo = null;
    try {
        VmwareManager mgr = context.getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
        VmwareHypervisorHost hyperHost = getHyperHost(context);
        dcMo = new DatacenterMO(hyperHost.getContext(), hyperHost.getHyperHostDatacenter());
        // Validate VM name is unique in Datacenter
        VirtualMachineMO vmInVcenter = dcMo.checkIfVmAlreadyExistsInVcenter(vmNameOnVcenter, vmInternalCSName);
        if (vmInVcenter != null) {
            vmAlreadyExistsInVcenter = true;
            String msg = "VM with name: " + vmNameOnVcenter + " already exists in vCenter.";
            s_logger.error(msg);
            throw new Exception(msg);
        }
        String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
        DiskTO[] disks = validateDisks(vmSpec.getDisks());
        assert (disks.length > 0);
        NicTO[] nics = vmSpec.getNics();
        HashMap<String, Pair<ManagedObjectReference, DatastoreMO>> dataStoresDetails = inferDatastoreDetailsFromDiskInfo(hyperHost, context, disks, cmd);
        if ((dataStoresDetails == null) || (dataStoresDetails.isEmpty())) {
            String msg = "Unable to locate datastore details of the volumes to be attached";
            s_logger.error(msg);
            throw new Exception(msg);
        }
        DatastoreMO dsRootVolumeIsOn = getDatastoreThatRootDiskIsOn(dataStoresDetails, disks);
        if (dsRootVolumeIsOn == null) {
            String msg = "Unable to locate datastore details of root volume";
            s_logger.error(msg);
            throw new Exception(msg);
        }
        VirtualMachineDiskInfoBuilder diskInfoBuilder = null;
        VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
        DiskControllerType systemVmScsiControllerType = DiskControllerType.lsilogic;
        int firstScsiControllerBusNum = 0;
        int numScsiControllerForSystemVm = 1;
        boolean hasSnapshot = false;
        if (vmMo != null) {
            s_logger.info("VM " + vmInternalCSName + " already exists, tear down devices for reconfiguration");
            if (getVmPowerState(vmMo) != PowerState.PowerOff)
                vmMo.safePowerOff(_shutdownWaitMs);
            // retrieve disk information before we tear down
            diskInfoBuilder = vmMo.getDiskInfoBuilder();
            hasSnapshot = vmMo.hasSnapshot();
            if (!hasSnapshot)
                vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
            else
                vmMo.tearDownDevices(new Class<?>[] { VirtualEthernetCard.class });
            if (systemVm) {
                ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
            } else {
                ensureDiskControllers(vmMo, controllerInfo);
            }
        } else {
            ManagedObjectReference morDc = hyperHost.getHyperHostDatacenter();
            assert (morDc != null);
            vmMo = hyperHost.findVmOnPeerHyperHost(vmInternalCSName);
            if (vmMo != null) {
                if (s_logger.isInfoEnabled()) {
                    s_logger.info("Found vm " + vmInternalCSName + " at other host, relocate to " + hyperHost.getHyperHostName());
                }
                takeVmFromOtherHyperHost(hyperHost, vmInternalCSName);
                if (getVmPowerState(vmMo) != PowerState.PowerOff)
                    vmMo.safePowerOff(_shutdownWaitMs);
                diskInfoBuilder = vmMo.getDiskInfoBuilder();
                hasSnapshot = vmMo.hasSnapshot();
                if (!hasSnapshot)
                    vmMo.tearDownDevices(new Class<?>[] { VirtualDisk.class, VirtualEthernetCard.class });
                else
                    vmMo.tearDownDevices(new Class<?>[] { VirtualEthernetCard.class });
                if (systemVm) {
                    // System volumes doesn't require more than 1 SCSI controller as there is no requirement for data volumes.
                    ensureScsiDiskControllers(vmMo, systemVmScsiControllerType.toString(), numScsiControllerForSystemVm, firstScsiControllerBusNum);
                } else {
                    ensureDiskControllers(vmMo, controllerInfo);
                }
            } else {
                // If a VM with the same name is found in a different cluster in the DC, unregister the old VM and configure a new VM (cold-migration).
                VirtualMachineMO existingVmInDc = dcMo.findVm(vmInternalCSName);
                if (existingVmInDc != null) {
                    s_logger.debug("Found VM: " + vmInternalCSName + " on a host in a different cluster. Unregistering the exisitng VM.");
                    existingVmName = existingVmInDc.getName();
                    existingVmFileInfo = existingVmInDc.getFileInfo();
                    existingVmFileLayout = existingVmInDc.getFileLayout();
                    existingVmInDc.unregisterVm();
                }
                Pair<ManagedObjectReference, DatastoreMO> rootDiskDataStoreDetails = null;
                for (DiskTO vol : disks) {
                    if (vol.getType() == Volume.Type.ROOT) {
                        Map<String, String> details = vol.getDetails();
                        boolean managed = false;
                        if (details != null) {
                            managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
                        }
                        if (managed) {
                            String datastoreName = VmwareResource.getDatastoreName(details.get(DiskTO.IQN));
                            rootDiskDataStoreDetails = dataStoresDetails.get(datastoreName);
                        } else {
                            DataStoreTO primaryStore = vol.getData().getDataStore();
                            rootDiskDataStoreDetails = dataStoresDetails.get(primaryStore.getUuid());
                        }
                    }
                }
                assert (vmSpec.getMinSpeed() != null) && (rootDiskDataStoreDetails != null);
                boolean vmFolderExists = rootDiskDataStoreDetails.second().folderExists(String.format("[%s]", rootDiskDataStoreDetails.second().getName()), vmNameOnVcenter);
                String vmxFileFullPath = dsRootVolumeIsOn.searchFileInSubFolders(vmNameOnVcenter + ".vmx", false);
                if (vmFolderExists && vmxFileFullPath != null) {
                    // VM can be registered only if .vmx is present.
                    registerVm(vmNameOnVcenter, dsRootVolumeIsOn);
                    vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
                    if (vmMo != null) {
                        if (s_logger.isDebugEnabled()) {
                            s_logger.debug("Found registered vm " + vmInternalCSName + " at host " + hyperHost.getHyperHostName());
                        }
                    }
                    tearDownVm(vmMo);
                } else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(), getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int) (vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), guestOsId, rootDiskDataStoreDetails.first(), false, controllerInfo, systemVm)) {
                    throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
                }
            }
            vmMo = hyperHost.findVmOnHyperHost(vmInternalCSName);
            if (vmMo == null) {
                throw new Exception("Failed to find the newly create or relocated VM. vmName: " + vmInternalCSName);
            }
        }
        int totalChangeDevices = disks.length + nics.length;
        DiskTO volIso = null;
        if (vmSpec.getType() != VirtualMachine.Type.User) {
            // system VM needs a patch ISO
            totalChangeDevices++;
        } else {
            volIso = getIsoDiskTO(disks);
            if (volIso == null)
                totalChangeDevices++;
        }
        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
        VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(), getReservedCpuMHZ(vmSpec), (int) (vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec), guestOsId, vmSpec.getLimitCpuUse());
        // Check for multi-cores per socket settings
        int numCoresPerSocket = 1;
        String coresPerSocket = vmSpec.getDetails().get("cpu.corespersocket");
        if (coresPerSocket != null) {
            String apiVersion = HypervisorHostHelper.getVcenterApiVersion(vmMo.getContext());
            // Property 'numCoresPerSocket' is supported since vSphere API 5.0
            if (apiVersion.compareTo("5.0") >= 0) {
                numCoresPerSocket = NumbersUtil.parseInt(coresPerSocket, 1);
                vmConfigSpec.setNumCoresPerSocket(numCoresPerSocket);
            }
        }
        // Check for hotadd settings
        vmConfigSpec.setMemoryHotAddEnabled(vmMo.isMemoryHotAddSupported(guestOsId));
        String hostApiVersion = ((HostMO) hyperHost).getHostAboutInfo().getApiVersion();
        if (numCoresPerSocket > 1 && hostApiVersion.compareTo("5.0") < 0) {
            s_logger.warn("Dynamic scaling of CPU is not supported for Virtual Machines with multi-core vCPUs in case of ESXi hosts 4.1 and prior. Hence CpuHotAdd will not be" + " enabled for Virtual Machine: " + vmInternalCSName);
            vmConfigSpec.setCpuHotAddEnabled(false);
        } else {
            vmConfigSpec.setCpuHotAddEnabled(vmMo.isCpuHotAddSupported(guestOsId));
        }
        configNestedHVSupport(vmMo, vmSpec, vmConfigSpec);
        VirtualDeviceConfigSpec[] deviceConfigSpecArray = new VirtualDeviceConfigSpec[totalChangeDevices];
        int i = 0;
        int ideUnitNumber = 0;
        int scsiUnitNumber = 0;
        int nicUnitNumber = 0;
        int ideControllerKey = vmMo.getIDEDeviceControllerKey();
        int scsiControllerKey = vmMo.getGenericScsiDeviceControllerKeyNoException();
        int controllerKey;
        // prepare systemvm patch ISO
        if (vmSpec.getType() != VirtualMachine.Type.User) {
            // attach ISO (for patching of system VM)
            Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
            String secStoreUrl = secStoreUrlAndId.first();
            Long secStoreId = secStoreUrlAndId.second();
            if (secStoreUrl == null) {
                String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
                throw new Exception(msg);
            }
            mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
            ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnHost(secStoreUrl);
            if (morSecDs == null) {
                String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
                throw new Exception(msg);
            }
            DatastoreMO secDsMo = new DatastoreMO(hyperHost.getContext(), morSecDs);
            deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
            Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, String.format("[%s] systemvm/%s", secDsMo.getName(), mgr.getSystemVMIsoFileNameOnDatastore()), secDsMo.getMor(), true, true, ideUnitNumber++, i + 1);
            deviceConfigSpecArray[i].setDevice(isoInfo.first());
            if (isoInfo.second()) {
                if (s_logger.isDebugEnabled())
                    s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
            } else {
                if (s_logger.isDebugEnabled())
                    s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
            }
        } else {
            // Note: we will always plug a CDROM device
            if (volIso != null) {
                TemplateObjectTO iso = (TemplateObjectTO) volIso.getData();
                if (iso.getPath() != null && !iso.getPath().isEmpty()) {
                    DataStoreTO imageStore = iso.getDataStore();
                    if (!(imageStore instanceof NfsTO)) {
                        s_logger.debug("unsupported protocol");
                        throw new Exception("unsupported protocol");
                    }
                    NfsTO nfsImageStore = (NfsTO) imageStore;
                    String isoPath = nfsImageStore.getUrl() + File.separator + iso.getPath();
                    Pair<String, ManagedObjectReference> isoDatastoreInfo = getIsoDatastoreInfo(hyperHost, isoPath);
                    assert (isoDatastoreInfo != null);
                    assert (isoDatastoreInfo.second() != null);
                    deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
                    Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, isoDatastoreInfo.first(), isoDatastoreInfo.second(), true, true, ideUnitNumber++, i + 1);
                    deviceConfigSpecArray[i].setDevice(isoInfo.first());
                    if (isoInfo.second()) {
                        if (s_logger.isDebugEnabled())
                            s_logger.debug("Prepare ISO volume at new device " + _gson.toJson(isoInfo.first()));
                        deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
                    } else {
                        if (s_logger.isDebugEnabled())
                            s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
                        deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
                    }
                }
            } else {
                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
                Pair<VirtualDevice, Boolean> isoInfo = VmwareHelper.prepareIsoDevice(vmMo, null, null, true, true, ideUnitNumber++, i + 1);
                deviceConfigSpecArray[i].setDevice(isoInfo.first());
                if (isoInfo.second()) {
                    if (s_logger.isDebugEnabled())
                        s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
                } else {
                    if (s_logger.isDebugEnabled())
                        s_logger.debug("Prepare ISO volume at existing device " + _gson.toJson(isoInfo.first()));
                    deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.EDIT);
                }
            }
        }
        i++;
        //
        // Setup ROOT/DATA disk devices
        //
        DiskTO[] sortedDisks = sortVolumesByDeviceId(disks);
        for (DiskTO vol : sortedDisks) {
            if (vol.getType() == Volume.Type.ISO)
                continue;
            VirtualMachineDiskInfo matchingExistingDisk = getMatchingExistingDisk(diskInfoBuilder, vol, hyperHost, context);
            controllerKey = getDiskController(matchingExistingDisk, vol, vmSpec, ideControllerKey, scsiControllerKey);
            String diskController = getDiskController(vmMo, matchingExistingDisk, vol, new Pair<String, String>(rootDiskController, dataDiskController));
            if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
                diskController = vmMo.getRecommendedDiskController(null);
            }
            if (DiskControllerType.getType(diskController) == DiskControllerType.ide) {
                controllerKey = vmMo.getIDEControllerKey(ideUnitNumber);
                if (vol.getType() == Volume.Type.DATADISK) {
                    // Ensure maximum of 2 data volumes over IDE controller, 3 includeing root volume
                    if (vmMo.getNumberOfVirtualDisks() > 3) {
                        throw new CloudRuntimeException("Found more than 3 virtual disks attached to this VM [" + vmMo.getVmName() + "]. Unable to implement the disks over " + diskController + " controller, as maximum number of devices supported over IDE controller is 4 includeing CDROM device.");
                    }
                }
            } else {
                controllerKey = vmMo.getScsiDiskControllerKeyNoException(diskController);
                if (controllerKey == -1) {
                    // This may happen for ROOT legacy VMs which doesn't have recommended disk controller when global configuration parameter 'vmware.root.disk.controller' is set to "osdefault"
                    // Retrieve existing controller and use.
                    Ternary<Integer, Integer, DiskControllerType> vmScsiControllerInfo = vmMo.getScsiControllerInfo();
                    DiskControllerType existingControllerType = vmScsiControllerInfo.third();
                    controllerKey = vmMo.getScsiDiskControllerKeyNoException(existingControllerType.toString());
                }
            }
            if (!hasSnapshot) {
                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
                VolumeObjectTO volumeTO = (VolumeObjectTO) vol.getData();
                DataStoreTO primaryStore = volumeTO.getDataStore();
                Map<String, String> details = vol.getDetails();
                boolean managed = false;
                String iScsiName = null;
                if (details != null) {
                    managed = Boolean.parseBoolean(details.get(DiskTO.MANAGED));
                    iScsiName = details.get(DiskTO.IQN);
                }
                // if the storage is managed, iScsiName should not be null
                String datastoreName = managed ? VmwareResource.getDatastoreName(iScsiName) : primaryStore.getUuid();
                Pair<ManagedObjectReference, DatastoreMO> volumeDsDetails = dataStoresDetails.get(datastoreName);
                assert (volumeDsDetails != null);
                String[] diskChain = syncDiskChain(dcMo, vmMo, vmSpec, vol, matchingExistingDisk, dataStoresDetails);
                if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
                    scsiUnitNumber++;
                VirtualDevice device = VmwareHelper.prepareDiskDevice(vmMo, null, controllerKey, diskChain, volumeDsDetails.first(), (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber)) ? ((ideUnitNumber++) % VmwareHelper.MAX_IDE_CONTROLLER_COUNT) : scsiUnitNumber++, i + 1);
                if (vol.getType() == Volume.Type.ROOT)
                    rootDiskTO = vol;
                deviceConfigSpecArray[i].setDevice(device);
                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
                if (s_logger.isDebugEnabled())
                    s_logger.debug("Prepare volume at new device " + _gson.toJson(device));
                i++;
            } else {
                if (controllerKey == scsiControllerKey && VmwareHelper.isReservedScsiDeviceNumber(scsiUnitNumber))
                    scsiUnitNumber++;
                if (controllerKey == vmMo.getIDEControllerKey(ideUnitNumber))
                    ideUnitNumber++;
                else
                    scsiUnitNumber++;
            }
        }
        //
        if (guestOsId.startsWith("darwin")) {
            //Mac OS
            VirtualDevice[] devices = vmMo.getMatchedDevices(new Class<?>[] { VirtualUSBController.class });
            if (devices.length == 0) {
                s_logger.debug("No USB Controller device on VM Start. Add USB Controller device for Mac OS VM " + vmInternalCSName);
                //For Mac OS X systems, the EHCI+UHCI controller is enabled by default and is required for USB mouse and keyboard access.
                VirtualDevice usbControllerDevice = VmwareHelper.prepareUSBControllerDevice();
                deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
                deviceConfigSpecArray[i].setDevice(usbControllerDevice);
                deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
                if (s_logger.isDebugEnabled())
                    s_logger.debug("Prepare USB controller at new device " + _gson.toJson(deviceConfigSpecArray[i]));
                i++;
            } else {
                s_logger.debug("USB Controller device exists on VM Start for Mac OS VM " + vmInternalCSName);
            }
        }
        //
        // Setup NIC devices
        //
        VirtualDevice nic;
        int nicMask = 0;
        int nicCount = 0;
        VirtualEthernetCardType nicDeviceType = VirtualEthernetCardType.valueOf(vmSpec.getDetails().get(VmDetailConstants.NIC_ADAPTER));
        if (s_logger.isDebugEnabled())
            s_logger.debug("VM " + vmInternalCSName + " will be started with NIC device type: " + nicDeviceType);
        NiciraNvpApiVersion.logNiciraApiVersion();
        Map<String, String> nicUuidToDvSwitchUuid = new HashMap<String, String>();
        for (NicTO nicTo : sortNicsByDeviceId(nics)) {
            s_logger.info("Prepare NIC device based on NicTO: " + _gson.toJson(nicTo));
            boolean configureVServiceInNexus = (nicTo.getType() == TrafficType.Guest) && (vmSpec.getDetails().containsKey("ConfigureVServiceInNexus"));
            VirtualMachine.Type vmType = cmd.getVirtualMachine().getType();
            Pair<ManagedObjectReference, String> networkInfo = prepareNetworkFromNicInfo(vmMo.getRunningHost(), nicTo, configureVServiceInNexus, vmType);
            if ((nicTo.getBroadcastType() != BroadcastDomainType.Lswitch) || (nicTo.getBroadcastType() == BroadcastDomainType.Lswitch && NiciraNvpApiVersion.isApiVersionLowerThan("4.2"))) {
                if (VmwareHelper.isDvPortGroup(networkInfo.first())) {
                    String dvSwitchUuid;
                    ManagedObjectReference dcMor = hyperHost.getHyperHostDatacenter();
                    DatacenterMO dataCenterMo = new DatacenterMO(context, dcMor);
                    ManagedObjectReference dvsMor = dataCenterMo.getDvSwitchMor(networkInfo.first());
                    dvSwitchUuid = dataCenterMo.getDvSwitchUuid(dvsMor);
                    s_logger.info("Preparing NIC device on dvSwitch : " + dvSwitchUuid);
                    nic = VmwareHelper.prepareDvNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), dvSwitchUuid, nicTo.getMac(), nicUnitNumber++, i + 1, true, true);
                    if (nicTo.getUuid() != null) {
                        nicUuidToDvSwitchUuid.put(nicTo.getUuid(), dvSwitchUuid);
                    }
                } else {
                    s_logger.info("Preparing NIC device on network " + networkInfo.second());
                    nic = VmwareHelper.prepareNicDevice(vmMo, networkInfo.first(), nicDeviceType, networkInfo.second(), nicTo.getMac(), nicUnitNumber++, i + 1, true, true);
                }
            } else {
                //if NSX API VERSION >= 4.2, connect to br-int (nsx.network), do not create portgroup else previous behaviour
                nic = VmwareHelper.prepareNicOpaque(vmMo, nicDeviceType, networkInfo.second(), nicTo.getMac(), nicUnitNumber++, i + 1, true, true);
            }
            deviceConfigSpecArray[i] = new VirtualDeviceConfigSpec();
            deviceConfigSpecArray[i].setDevice(nic);
            deviceConfigSpecArray[i].setOperation(VirtualDeviceConfigSpecOperation.ADD);
            if (s_logger.isDebugEnabled())
                s_logger.debug("Prepare NIC at new device " + _gson.toJson(deviceConfigSpecArray[i]));
            // this is really a hacking for DomR, upon DomR startup, we will reset all the NIC allocation after eth3
            if (nicCount < 3)
                nicMask |= (1 << nicCount);
            i++;
            nicCount++;
        }
        for (int j = 0; j < i; j++) vmConfigSpec.getDeviceChange().add(deviceConfigSpecArray[j]);
        //
        // Setup VM options
        //
        // pass boot arguments through machine.id & perform customized options to VMX
        ArrayList<OptionValue> extraOptions = new ArrayList<OptionValue>();
        configBasicExtraOption(extraOptions, vmSpec);
        configNvpExtraOption(extraOptions, vmSpec, nicUuidToDvSwitchUuid);
        configCustomExtraOption(extraOptions, vmSpec);
        // config VNC
        String keyboardLayout = null;
        if (vmSpec.getDetails() != null)
            keyboardLayout = vmSpec.getDetails().get(VmDetailConstants.KEYBOARD);
        vmConfigSpec.getExtraConfig().addAll(Arrays.asList(configureVnc(extraOptions.toArray(new OptionValue[0]), hyperHost, vmInternalCSName, vmSpec.getVncPassword(), keyboardLayout)));
        // config video card
        configureVideoCard(vmMo, vmSpec, vmConfigSpec);
        //
        if (!vmMo.configureVm(vmConfigSpec)) {
            throw new Exception("Failed to configure VM before start. vmName: " + vmInternalCSName);
        }
        if (vmSpec.getType() == VirtualMachine.Type.DomainRouter) {
            hyperHost.setRestartPriorityForVM(vmMo, DasVmPriority.HIGH.value());
        }
        //For resizing root disk.
        if (rootDiskTO != null && !hasSnapshot) {
            resizeRootDisk(vmMo, rootDiskTO, hyperHost, context);
        }
        //
        // Post Configuration
        //
        vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, String.valueOf(nicMask));
        postNvpConfigBeforeStart(vmMo, vmSpec);
        Map<String, String> iqnToPath = new HashMap<String, String>();
        postDiskConfigBeforeStart(vmMo, vmSpec, sortedDisks, ideControllerKey, scsiControllerKey, iqnToPath, hyperHost, context);
        //
        if (!vmMo.powerOn()) {
            throw new Exception("Failed to start VM. vmName: " + vmInternalCSName + " with hostname " + vmNameOnVcenter);
        }
        StartAnswer startAnswer = new StartAnswer(cmd);
        startAnswer.setIqnToPath(iqnToPath);
        // Since VM was successfully powered-on, if there was an existing VM in a different cluster that was unregistered, delete all the files associated with it.
        if (existingVmName != null && existingVmFileLayout != null) {
            deleteUnregisteredVmFiles(existingVmFileLayout, dcMo, true);
        }
        return startAnswer;
    } catch (Throwable e) {
        if (e instanceof RemoteException) {
            s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
            invalidateServiceContext();
        }
        String msg = "StartCommand failed due to " + VmwareHelper.getExceptionMessage(e);
        s_logger.warn(msg, e);
        StartAnswer startAnswer = new StartAnswer(cmd, msg);
        if (vmAlreadyExistsInVcenter) {
            startAnswer.setContextParam("stopRetry", "true");
        }
        // Since VM start failed, if there was an existing VM in a different cluster that was unregistered, register it back.
        if (existingVmName != null && existingVmFileInfo != null) {
            s_logger.debug("Since VM start failed, registering back an existing VM: " + existingVmName + " that was unregistered");
            try {
                DatastoreFile fileInDatastore = new DatastoreFile(existingVmFileInfo.getVmPathName());
                DatastoreMO existingVmDsMo = new DatastoreMO(dcMo.getContext(), dcMo.findDatastore(fileInDatastore.getDatastoreName()));
                registerVm(existingVmName, existingVmDsMo);
            } catch (Exception ex) {
                String message = "Failed to register an existing VM: " + existingVmName + " due to " + VmwareHelper.getExceptionMessage(ex);
                s_logger.warn(message, ex);
            }
        }
        return startAnswer;
    } finally {
    }
}
Also used : StartAnswer(com.cloud.agent.api.StartAnswer) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) VirtualMachineTO(com.cloud.agent.api.to.VirtualMachineTO) DatastoreFile(com.cloud.hypervisor.vmware.mo.DatastoreFile) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) VirtualMachineFileLayoutEx(com.vmware.vim25.VirtualMachineFileLayoutEx) NicTO(com.cloud.agent.api.to.NicTO) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) VmwareManager(com.cloud.hypervisor.vmware.manager.VmwareManager) VirtualMachineMO(com.cloud.hypervisor.vmware.mo.VirtualMachineMO) VirtualDevice(com.vmware.vim25.VirtualDevice) VirtualMachineDiskInfoBuilder(com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder) NfsTO(com.cloud.agent.api.to.NfsTO) DatastoreMO(com.cloud.hypervisor.vmware.mo.DatastoreMO) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) DatacenterMO(com.cloud.hypervisor.vmware.mo.DatacenterMO) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference) VirtualMachine(com.cloud.vm.VirtualMachine) VirtualDeviceConfigSpec(com.vmware.vim25.VirtualDeviceConfigSpec) DiskControllerType(com.cloud.hypervisor.vmware.mo.DiskControllerType) VirtualMachineConfigSpec(com.vmware.vim25.VirtualMachineConfigSpec) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VirtualMachineDiskInfo(org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo) OptionValue(com.vmware.vim25.OptionValue) VirtualEthernetCard(com.vmware.vim25.VirtualEthernetCard) Pair(com.cloud.utils.Pair) VirtualEthernetCardType(com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) ConnectException(java.net.ConnectException) IOException(java.io.IOException) RemoteException(java.rmi.RemoteException) InternalErrorException(com.cloud.exception.InternalErrorException) CloudException(com.cloud.exception.CloudException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ConfigurationException(javax.naming.ConfigurationException) VirtualDisk(com.vmware.vim25.VirtualDisk) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) RemoteException(java.rmi.RemoteException) VirtualMachineFileInfo(com.vmware.vim25.VirtualMachineFileInfo) DiskTO(com.cloud.agent.api.to.DiskTO)

Example 34 with Network

use of com.vmware.vim25.mo.Network in project cloudstack by apache.

the class VmwareResource method prepareNetworkFromNicInfo.

private Pair<ManagedObjectReference, String> prepareNetworkFromNicInfo(HostMO hostMo, NicTO nicTo, boolean configureVServiceInNexus, VirtualMachine.Type vmType) throws Exception {
    Ternary<String, String, String> switchDetails = getTargetSwitch(nicTo);
    VirtualSwitchType switchType = VirtualSwitchType.getType(switchDetails.second());
    String switchName = switchDetails.first();
    String vlanToken = switchDetails.third();
    String namePrefix = getNetworkNamePrefix(nicTo);
    Pair<ManagedObjectReference, String> networkInfo = null;
    s_logger.info("Prepare network on " + switchType + " " + switchName + " with name prefix: " + namePrefix);
    if (VirtualSwitchType.StandardVirtualSwitch == switchType) {
        networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, getVlanInfo(nicTo, vlanToken), nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, !namePrefix.startsWith("cloud.private"), nicTo.getBroadcastType(), nicTo.getUuid());
    } else {
        String vlanId = getVlanInfo(nicTo, vlanToken);
        String svlanId = null;
        boolean pvlannetwork = (getPvlanInfo(nicTo) == null) ? false : true;
        if (vmType != null && vmType.equals(VirtualMachine.Type.DomainRouter) && pvlannetwork) {
            // plumb this network to the promiscuous vlan.
            svlanId = vlanId;
        } else {
            // plumb this network to the isolated vlan.
            svlanId = getPvlanInfo(nicTo);
        }
        networkInfo = HypervisorHostHelper.prepareNetwork(switchName, namePrefix, hostMo, vlanId, svlanId, nicTo.getNetworkRateMbps(), nicTo.getNetworkRateMulticastMbps(), _opsTimeout, switchType, _portsPerDvPortGroup, nicTo.getGateway(), configureVServiceInNexus, nicTo.getBroadcastType(), _vsmCredentials);
    }
    return networkInfo;
}
Also used : VirtualSwitchType(com.cloud.hypervisor.vmware.mo.VirtualSwitchType) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Example 35 with Network

use of com.vmware.vim25.mo.Network in project cloudstack by apache.

the class VmwareServerDiscoverer method find.

@Override
public Map<? extends ServerResource, Map<String, String>> find(long dcId, Long podId, Long clusterId, URI url, String username, String password, List<String> hostTags) throws DiscoveryException {
    if (s_logger.isInfoEnabled())
        s_logger.info("Discover host. dc: " + dcId + ", pod: " + podId + ", cluster: " + clusterId + ", uri host: " + url.getHost());
    if (podId == null) {
        if (s_logger.isInfoEnabled())
            s_logger.info("No pod is assigned, assuming that it is not for vmware and skip it to next discoverer");
        return null;
    }
    boolean failureInClusterDiscovery = true;
    String vsmIp = "";
    ClusterVO cluster = _clusterDao.findById(clusterId);
    if (cluster == null || cluster.getHypervisorType() != HypervisorType.VMware) {
        if (s_logger.isInfoEnabled())
            s_logger.info("invalid cluster id or cluster is not for VMware hypervisors");
        return null;
    }
    Map<String, String> clusterDetails = _clusterDetailsDao.findDetails(clusterId);
    boolean legacyZone = _vmwareMgr.isLegacyZone(dcId);
    boolean usernameNotProvided = (username == null || username.isEmpty());
    boolean passwordNotProvided = (password == null || password.isEmpty());
    //Check if NOT a legacy zone.
    if (!legacyZone) {
        // Retrieve VMware DC associated with specified zone
        VmwareDatacenterVO vmwareDc = fetchVmwareDatacenterByZone(dcId);
        // If either or both not provided, try to retrieve & use the credentials from database, which are provided earlier while adding VMware DC to zone.
        if (usernameNotProvided || passwordNotProvided) {
            // Retrieve credentials associated with VMware DC
            s_logger.info("Username and/or Password not provided while adding cluster to cloudstack zone. " + "Hence using both username & password provided while adding VMware DC to CloudStack zone.");
            username = vmwareDc.getUser();
            password = vmwareDc.getPassword();
            clusterDetails.put("username", username);
            clusterDetails.put("password", password);
            _clusterDetailsDao.persist(clusterId, clusterDetails);
        }
        String updatedInventoryPath = validateCluster(url, vmwareDc);
        try {
            if (!URLDecoder.decode(url.getPath(), "UTF-8").equals(updatedInventoryPath)) {
                // If url from API doesn't specify DC then update url in database with DC associated with this zone.
                clusterDetails.put("url", url.getScheme() + "://" + url.getHost() + updatedInventoryPath);
                _clusterDetailsDao.persist(clusterId, clusterDetails);
            }
        } catch (UnsupportedEncodingException e) {
            throw new DiscoveredWithErrorException("Unable to decode URL path, URL path : " + url.getPath(), e);
        }
    } else {
        // For legacy zones insist on the old model of asking for credentials for each cluster being added.
        if (usernameNotProvided) {
            if (passwordNotProvided) {
                throw new InvalidParameterValueException("Please provide username & password to add this cluster to zone");
            } else {
                throw new InvalidParameterValueException("Please provide username to add this cluster to zone");
            }
        } else if (passwordNotProvided) {
            throw new InvalidParameterValueException("Please provide password to add this cluster to zone");
        }
    }
    List<HostVO> hosts = _resourceMgr.listAllHostsInCluster(clusterId);
    if (hosts != null && hosts.size() > 0) {
        int maxHostsPerCluster = _hvCapabilitiesDao.getMaxHostsPerCluster(hosts.get(0).getHypervisorType(), hosts.get(0).getHypervisorVersion());
        if (hosts.size() >= maxHostsPerCluster) {
            String msg = "VMware cluster " + cluster.getName() + " is too big to add new host, current size: " + hosts.size() + ", max. size: " + maxHostsPerCluster;
            s_logger.error(msg);
            throw new DiscoveredWithErrorException(msg);
        }
    }
    String privateTrafficLabel = null;
    String publicTrafficLabel = null;
    String guestTrafficLabel = null;
    Map<String, String> vsmCredentials = null;
    VirtualSwitchType defaultVirtualSwitchType = VirtualSwitchType.StandardVirtualSwitch;
    String paramGuestVswitchType = null;
    String paramGuestVswitchName = null;
    String paramPublicVswitchType = null;
    String paramPublicVswitchName = null;
    VmwareTrafficLabel guestTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Guest);
    VmwareTrafficLabel publicTrafficLabelObj = new VmwareTrafficLabel(TrafficType.Public);
    DataCenterVO zone = _dcDao.findById(dcId);
    NetworkType zoneType = zone.getNetworkType();
    _readGlobalConfigParameters();
    // Private traffic will be only on standard vSwitch for now.
    if (useDVS) {
        // Parse url parameters for type of vswitch and name of vswitch specified at cluster level
        paramGuestVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_GUEST_TRAFFIC);
        paramGuestVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_GUEST_TRAFFIC);
        paramPublicVswitchType = _urlParams.get(ApiConstants.VSWITCH_TYPE_PUBLIC_TRAFFIC);
        paramPublicVswitchName = _urlParams.get(ApiConstants.VSWITCH_NAME_PUBLIC_TRAFFIC);
        defaultVirtualSwitchType = getDefaultVirtualSwitchType();
    }
    // Zone level vSwitch Type depends on zone level traffic labels
    //
    // User can override Zone wide vswitch type (for public and guest) by providing following optional parameters in addClusterCmd
    // param "guestvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs
    // param "publicvswitchtype" with valid values vmwaredvs, vmwaresvs, nexusdvs
    //
    // Format of label is <VSWITCH>,<VLANID>,<VSWITCHTYPE>
    // If a field <VLANID> OR <VSWITCHTYPE> is not present leave it empty.
    // Ex: 1) vswitch0
    // 2) dvswitch0,200,vmwaredvs
    // 3) nexusepp0,300,nexusdvs
    // 4) vswitch1,400,vmwaresvs
    // 5) vswitch0
    // default vswitchtype is 'vmwaresvs'.
    // <VSWITCHTYPE> 'vmwaresvs' is for vmware standard vswitch
    // <VSWITCHTYPE> 'vmwaredvs' is for vmware distributed virtual switch
    // <VSWITCHTYPE> 'nexusdvs' is for cisco nexus distributed virtual switch
    // Get zone wide traffic labels for Guest traffic and Public traffic
    guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware);
    // Process traffic label information provided at zone level and cluster level
    guestTrafficLabelObj = getTrafficInfo(TrafficType.Guest, guestTrafficLabel, defaultVirtualSwitchType, paramGuestVswitchType, paramGuestVswitchName, clusterId);
    if (zoneType == NetworkType.Advanced) {
        // Get zone wide traffic label for Public traffic
        publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware);
        // Process traffic label information provided at zone level and cluster level
        publicTrafficLabelObj = getTrafficInfo(TrafficType.Public, publicTrafficLabel, defaultVirtualSwitchType, paramPublicVswitchType, paramPublicVswitchName, clusterId);
        // Configuration Check: A physical network cannot be shared by different types of virtual switches.
        //
        // Check if different vswitch types are chosen for same physical network
        // 1. Get physical network for guest traffic - multiple networks
        // 2. Get physical network for public traffic - single network
        // See if 2 is in 1
        //  if no - pass
        //  if yes - compare publicTrafficLabelObj.getVirtualSwitchType() == guestTrafficLabelObj.getVirtualSwitchType()
        //      true  - pass
        //      false - throw exception - fail cluster add operation
        List<? extends PhysicalNetwork> pNetworkListGuestTraffic = _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Guest);
        List<? extends PhysicalNetwork> pNetworkListPublicTraffic = _netmgr.getPhysicalNtwksSupportingTrafficType(dcId, TrafficType.Public);
        // Public network would be on single physical network hence getting first object of the list would suffice.
        PhysicalNetwork pNetworkPublic = pNetworkListPublicTraffic.get(0);
        if (pNetworkListGuestTraffic.contains(pNetworkPublic)) {
            if (publicTrafficLabelObj.getVirtualSwitchType() != guestTrafficLabelObj.getVirtualSwitchType()) {
                String msg = "Both public traffic and guest traffic is over same physical network " + pNetworkPublic + ". And virtual switch type chosen for each traffic is different" + ". A physical network cannot be shared by different types of virtual switches.";
                s_logger.error(msg);
                throw new InvalidParameterValueException(msg);
            }
        }
    }
    privateTrafficLabel = _netmgr.getDefaultManagementTrafficLabel(dcId, HypervisorType.VMware);
    if (privateTrafficLabel != null) {
        s_logger.info("Detected private network label : " + privateTrafficLabel);
    }
    Pair<Boolean, Long> vsmInfo = new Pair<Boolean, Long>(false, 0L);
    if (nexusDVS && (guestTrafficLabelObj.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch) || ((zoneType == NetworkType.Advanced) && (publicTrafficLabelObj.getVirtualSwitchType() == VirtualSwitchType.NexusDistributedVirtualSwitch))) {
        // 2) Atleast 1 traffic type uses Nexus distributed virtual switch as backend.
        if (zoneType != NetworkType.Basic) {
            publicTrafficLabel = _netmgr.getDefaultPublicTrafficLabel(dcId, HypervisorType.VMware);
            if (publicTrafficLabel != null) {
                s_logger.info("Detected public network label : " + publicTrafficLabel);
            }
        }
        // Get physical network label
        guestTrafficLabel = _netmgr.getDefaultGuestTrafficLabel(dcId, HypervisorType.VMware);
        if (guestTrafficLabel != null) {
            s_logger.info("Detected guest network label : " + guestTrafficLabel);
        }
        // Before proceeding with validation of Nexus 1000v VSM check if an instance of Nexus 1000v VSM is already associated with this cluster.
        boolean clusterHasVsm = _vmwareMgr.hasNexusVSM(clusterId);
        if (!clusterHasVsm) {
            vsmIp = _urlParams.get("vsmipaddress");
            String vsmUser = _urlParams.get("vsmusername");
            String vsmPassword = _urlParams.get("vsmpassword");
            String clusterName = cluster.getName();
            try {
                vsmInfo = _nexusElement.validateAndAddVsm(vsmIp, vsmUser, vsmPassword, clusterId, clusterName);
            } catch (ResourceInUseException ex) {
                DiscoveryException discEx = new DiscoveryException(ex.getLocalizedMessage() + ". The resource is " + ex.getResourceName());
                throw discEx;
            }
        }
        vsmCredentials = _vmwareMgr.getNexusVSMCredentialsByClusterId(clusterId);
    }
    VmwareContext context = null;
    try {
        context = VmwareContextFactory.create(url.getHost(), username, password);
        if (privateTrafficLabel != null)
            context.registerStockObject("privateTrafficLabel", privateTrafficLabel);
        if (nexusDVS) {
            if (vsmCredentials != null) {
                s_logger.info("Stocking credentials of Nexus VSM");
                context.registerStockObject("vsmcredentials", vsmCredentials);
            }
        }
        List<ManagedObjectReference> morHosts = _vmwareMgr.addHostToPodCluster(context, dcId, podId, clusterId, URLDecoder.decode(url.getPath(), "UTF-8"));
        if (morHosts == null)
            s_logger.info("Found 0 hosts.");
        if (privateTrafficLabel != null)
            context.uregisterStockObject("privateTrafficLabel");
        if (morHosts == null) {
            s_logger.error("Unable to find host or cluster based on url: " + URLDecoder.decode(url.getPath(), "UTF-8"));
            return null;
        }
        ManagedObjectReference morCluster = null;
        clusterDetails = _clusterDetailsDao.findDetails(clusterId);
        if (clusterDetails.get("url") != null) {
            URI uriFromCluster = new URI(UriUtils.encodeURIComponent(clusterDetails.get("url")));
            morCluster = context.getHostMorByPath(URLDecoder.decode(uriFromCluster.getPath(), "UTF-8"));
            if (morCluster == null || !morCluster.getType().equalsIgnoreCase("ClusterComputeResource")) {
                s_logger.warn("Cluster url does not point to a valid vSphere cluster, url: " + clusterDetails.get("url"));
                return null;
            } else {
                ClusterMO clusterMo = new ClusterMO(context, morCluster);
                if (clusterMo.isHAEnabled()) {
                    clusterDetails.put("NativeHA", "true");
                    _clusterDetailsDao.persist(clusterId, clusterDetails);
                }
            }
        }
        if (!validateDiscoveredHosts(context, morCluster, morHosts)) {
            if (morCluster == null)
                s_logger.warn("The discovered host is not standalone host, can not be added to a standalone cluster");
            else
                s_logger.warn("The discovered host does not belong to the cluster");
            return null;
        }
        Map<VmwareResource, Map<String, String>> resources = new HashMap<VmwareResource, Map<String, String>>();
        for (ManagedObjectReference morHost : morHosts) {
            Map<String, String> details = new HashMap<String, String>();
            Map<String, Object> params = new HashMap<String, Object>();
            HostMO hostMo = new HostMO(context, morHost);
            details.put("url", hostMo.getHostName());
            details.put("username", username);
            details.put("password", password);
            String guid = morHost.getType() + ":" + morHost.getValue() + "@" + url.getHost();
            details.put("guid", guid);
            params.put("url", hostMo.getHostName());
            params.put("username", username);
            params.put("password", password);
            params.put("zone", Long.toString(dcId));
            params.put("pod", Long.toString(podId));
            params.put("cluster", Long.toString(clusterId));
            params.put("guid", guid);
            if (privateTrafficLabel != null) {
                params.put("private.network.vswitch.name", privateTrafficLabel);
            }
            params.put("guestTrafficInfo", guestTrafficLabelObj);
            params.put("publicTrafficInfo", publicTrafficLabelObj);
            params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString()));
            VmwareResource resource = new VmwareResource();
            try {
                resource.configure("VMware", params);
            } catch (ConfigurationException e) {
                _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_HOST, dcId, podId, "Unable to add " + url.getHost(), "Error is " + e.getMessage());
                s_logger.warn("Unable to instantiate " + url.getHost(), e);
            }
            resource.start();
            resources.put(resource, details);
        }
        // place a place holder guid derived from cluster ID
        try {
            cluster.setGuid(UUID.nameUUIDFromBytes(String.valueOf(clusterId).getBytes("UTF-8")).toString());
        } catch (UnsupportedEncodingException e) {
            throw new DiscoveredWithErrorException("Unable to create UUID based on string " + String.valueOf(clusterId) + ". Bad clusterId or UTF-8 encoding error.");
        }
        _clusterDao.update(clusterId, cluster);
        // Flag cluster discovery success
        failureInClusterDiscovery = false;
        return resources;
    } catch (DiscoveredWithErrorException e) {
        throw e;
    } catch (Exception e) {
        s_logger.warn("Unable to connect to Vmware vSphere server. service address: " + url.getHost() + ". " + e);
        return null;
    } finally {
        if (context != null)
            context.close();
        if (failureInClusterDiscovery && vsmInfo.first()) {
            try {
                s_logger.debug("Deleting Nexus 1000v VSM " + vsmIp + " because cluster discovery and addition to zone has failed.");
                _nexusElement.deleteCiscoNexusVSM(vsmInfo.second().longValue());
            } catch (Exception e) {
                s_logger.warn("Deleting Nexus 1000v VSM " + vsmIp + " failed.");
            }
        }
    }
}
Also used : VmwareTrafficLabel(com.cloud.network.VmwareTrafficLabel) VmwareResource(com.cloud.hypervisor.vmware.resource.VmwareResource) HashMap(java.util.HashMap) HostMO(com.cloud.hypervisor.vmware.mo.HostMO) ClusterMO(com.cloud.hypervisor.vmware.mo.ClusterMO) URI(java.net.URI) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ConfigurationException(javax.naming.ConfigurationException) NetworkType(com.cloud.dc.DataCenter.NetworkType) PhysicalNetwork(com.cloud.network.PhysicalNetwork) ResourceInUseException(com.cloud.exception.ResourceInUseException) DiscoveryException(com.cloud.exception.DiscoveryException) Pair(com.cloud.utils.Pair) DataCenterVO(com.cloud.dc.DataCenterVO) ClusterVO(com.cloud.dc.ClusterVO) UnsupportedEncodingException(java.io.UnsupportedEncodingException) DiscoveredWithErrorException(com.cloud.exception.DiscoveredWithErrorException) HostVO(com.cloud.host.HostVO) DiscoveredWithErrorException(com.cloud.exception.DiscoveredWithErrorException) DiscoveryException(com.cloud.exception.DiscoveryException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ConfigurationException(javax.naming.ConfigurationException) UnableDeleteHostException(com.cloud.resource.UnableDeleteHostException) ResourceInUseException(com.cloud.exception.ResourceInUseException) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) VirtualSwitchType(com.cloud.hypervisor.vmware.mo.VirtualSwitchType) Map(java.util.Map) HashMap(java.util.HashMap) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Aggregations

ManagedObjectReference (com.vmware.vim25.ManagedObjectReference)23 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)12 ObjectContent (com.vmware.vim25.ObjectContent)12 ObjectSpec (com.vmware.vim25.ObjectSpec)12 PropertyFilterSpec (com.vmware.vim25.PropertyFilterSpec)12 PropertySpec (com.vmware.vim25.PropertySpec)12 TraversalSpec (com.vmware.vim25.TraversalSpec)12 ArrayList (java.util.ArrayList)11 CloudException (com.cloud.exception.CloudException)10 DynamicProperty (com.vmware.vim25.DynamicProperty)10 IOException (java.io.IOException)10 RemoteException (java.rmi.RemoteException)10 UnsupportedEncodingException (java.io.UnsupportedEncodingException)9 Pair (com.cloud.utils.Pair)8 ConfigurationException (javax.naming.ConfigurationException)8 InternalErrorException (com.cloud.exception.InternalErrorException)7 HostMO (com.cloud.hypervisor.vmware.mo.HostMO)7 VmwareContext (com.cloud.hypervisor.vmware.util.VmwareContext)7 ConnectException (java.net.ConnectException)7 VmwareHypervisorHost (com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost)6