vmware vsphere 虚拟机 VirtualMachine

VirtualMachine 虚拟机

public class InstanceServiceImpl implements IInstanceService {
@Autowired
private CloudNetworkMapper cloudNetworkMapper;
@Autowired
private StringRedisTemplate redisTemplate;

@Autowired
private VcenterClient vcenterClient;

@Autowired
private CloudInstanceMapper cloudInstanceMapper;



@Autowired
private CloudSyncInvoke cloudSyncInvoke;

private static String errorName = TypeIdEnums.getName(TypeIdEnums.TYPE_VM.getTypeid())+"##InstanceServiceImpl##";

int portStart = 5900;
int portEnd = 6080;

/**
 *  关机、os-stop | 开机、os-start | 挂起、suspend | 重置-硬操作;相当于暴力重启reset
 *  重启-软操作;使用脚本关机在重启、soft-reboot | 重启-硬操作;相当于暴力重启、hard-reboot | 删除、delete
 * @param si
 * @param data
 * @return
 */
@Override
public boolean dovcAction(ServiceInstance si, VcActionRequestParam data) {
    log.info(errorName+"dovcAction##VcActionRequestParam={}", JSONUtil.toJsonStr(data));
    try {
        VirtualMachine vm = getVirtualMachine(si, getDatacenter(si, data.getVcenterName()), data.getServerId());
        Task task = null;
        switch (data.getAction()) {
            case "os-stop":
                task = vm.powerOffVM_Task();
                break;
            case "os-start":
                task = vm.powerOnVM_Task(null);
                break;
            case "suspend":
                task = vm.suspendVM_Task();
                break;
            case "reset":
                task = vm.resetVM_Task();
                break;
            case "soft-reboot":
                vm.rebootGuest();
                break;
            case "hard-reboot":
                task = vm.resetVM_Task();
                break;
            case "delete":
                if (vm == null) {
                    String vmPathName = data.getVmPathName();
                    vm = (VirtualMachine) si.getSearchIndex().findByDatastorePath(getDatacenter(si, data.getVcenterName()), vmPathName);
                }
                //判断虚拟机是否断电
                if (!vm.getRuntime().getPowerState().name().equalsIgnoreCase(VirtualMachinePowerState.poweredOff.name())){
                    task = vm.powerOffVM_Task();
                    if(!Task.SUCCESS.equals(task.waitForTask())){
                      throw new CloudResourcesException(CloudResourcesErrorEnum.INSTANCE_POWER_ERROR);
                    }
                }
                task = vm.destroy_Task();
                break;
            default:
                log.info(errorName+"dovcAction##get action={}", JSONUtil.toJsonStr(data.getAction()));
                break;
        }

        //返回true
        if (Task.SUCCESS == task.waitForTask()) {
            return true;
        }
    } catch (Exception e) {
        throw new CloudResourcesException(CloudResourcesErrorEnum.ACTION_ERROR);
    } finally {
        vcenterClient.closeConnection(si);
    }
    return false;
}


//调整流量
@Override
public Task trafficShaping(ServiceInstance si, VcTrafficShappingReq req, String net) throws RemoteException {
    log.info(errorName+"trafficShaping##VcTrafficShappingReq={}##net={}", JSONUtil.toJsonStr(req),net);
    Task task = null;
    Folder rootFolder = si.getRootFolder();
    ManagedEntity mes = new InventoryNavigator(rootFolder).searchManagedEntity("Datacenter", req.getDcName());
    Datacenter dc = (Datacenter) mes;
    DistributedVirtualPortgroup dvp = (DistributedVirtualPortgroup) new InventoryNavigator(dc)
            .searchManagedEntity("DistributedVirtualPortgroup", net);
    DVPortgroupConfigInfo info = dvp.getConfig();
    DVPortgroupConfigSpec config = new DVPortgroupConfigSpec();
    config.setConfigVersion(info.getConfigVersion());
    DVPortgroupPolicy dp = new DVPortgroupPolicy();
    dp.setBlockOverrideAllowed(true);
    dp.setPortConfigResetAtDisconnect(true);
    dp.setShapingOverrideAllowed(true);
    config.setPolicy(dp);
    dvp.reconfigureDVPortgroup_Task(config);
    /** 查找所属dvs **/
    ManagedEntity[] dvs = new InventoryNavigator(dc).searchManagedEntities("DistributedVirtualSwitch");
    String dvsName = "";
    for (ManagedEntity dvsEntity : dvs) {
        DistributedVirtualSwitch model = (DistributedVirtualSwitch) dvsEntity;
        DistributedVirtualPortgroup[] tempList = model.getPortgroup();
        if (null == tempList) {
            continue;
        }
        for (DistributedVirtualPortgroup m : tempList) {
            if (dvp.getKey().equals(m.getKey())) {
                dvsName = model.getName();
                break;
            }
        }
    }
    // 所在vm码
    ManagedEntity[] ens = new InventoryNavigator(rootFolder)
            .searchManagedEntities(VcenterConstantUtils.Vcenter.ManagedEntityType.VirtualMachine);
    String vmor = "";
    for (ManagedEntity vm : ens) {
        VirtualMachine v = (VirtualMachine) vm;
        // vm名
        if (req.getInstanceUuid().equals(v.getConfig().getInstanceUuid())) {
            vmor = v.getMOR().getVal();
            break;
        }
    }
    // 交换机
    DistributedVirtualSwitch dis = (DistributedVirtualSwitch) new InventoryNavigator(dc)
            .searchManagedEntity("DistributedVirtualSwitch", dvsName);
    // 交换机下所有端口
    DistributedVirtualSwitchPortCriteria criteria = new DistributedVirtualSwitchPortCriteria();
    criteria.setConnected(true);
    DistributedVirtualPort[] p = dis.fetchDVPorts(criteria);

    for (DistributedVirtualPort port : p) {
        // 端口vm码
        DistributedVirtualSwitchPortConnectee dvspc = port.getConnectee();
        if (null == dvspc) {
            continue;
        } else {
            String s = dvspc.getConnectedEntity().getVal();
            if (s.equals(vmor)) {
                DistributedVirtualPort e = port;
                DVPortConfigSpec dpcs = new DVPortConfigSpec();
                dpcs.setConfigVersion(e.getConfig().getConfigVersion());
                dpcs.setKey(e.getKey());
                dpcs.setOperation("edit");

                DVPortSetting svps = new DVPortSetting();
                svps.setVmDirectPathGen2Allowed(e.getConfig().getSetting().getVmDirectPathGen2Allowed());
                svps.setVendorSpecificConfig(e.getConfig().getSetting().getVendorSpecificConfig());
                svps.setNetworkResourcePoolKey(e.getConfig().getSetting().getNetworkResourcePoolKey());
                svps.setFilterPolicy(e.getConfig().getSetting().getFilterPolicy());
                svps.setBlocked(e.getConfig().getSetting().getBlocked());
                DVSTrafficShapingPolicy inShapingPolicy = new DVSTrafficShapingPolicy();
                BoolPolicy boolIn = new BoolPolicy();
                if (req.getInAverageBandwidth() == -1) {
                    boolIn.setValue(false);
                    inShapingPolicy.setEnabled(boolIn);
                } else {
                    boolIn.setValue(true);
                    inShapingPolicy.setEnabled(boolIn);
                    LongPolicy inAverageB = new LongPolicy();
                    inAverageB.setValue(1000 * req.getInAverageBandwidth());
                    LongPolicy inPeakB = new LongPolicy();
                    inPeakB.setValue(1000 * req.getInPeakBandwidth());
                    LongPolicy inBurstS = new LongPolicy();
                    inBurstS.setValue(1000 * (req.getInBurstSize()));
                    inShapingPolicy.setAverageBandwidth(inAverageB);
                    inShapingPolicy.setPeakBandwidth(inPeakB);
                    inShapingPolicy.setBurstSize(inBurstS);
                }
                svps.setInShapingPolicy(inShapingPolicy);

                DVSTrafficShapingPolicy outShapingPolicy = new DVSTrafficShapingPolicy();
                BoolPolicy boolOut = new BoolPolicy();
                if (req.getOutAverageBandwidth() == -1) {
                    boolOut.setValue(false);
                    outShapingPolicy.setEnabled(boolOut);
                } else {
                    boolOut.setValue(true);
                    outShapingPolicy.setEnabled(boolOut);
                    LongPolicy outAverageB = new LongPolicy();
                    outAverageB.setValue(1000 * req.getOutAverageBandwidth());
                    LongPolicy outPeakB = new LongPolicy();
                    outPeakB.setValue(1000 * req.getOutPeakBandwidth());
                    LongPolicy outBurstS = new LongPolicy();
                    outBurstS.setValue(1000 * (req.getOutBurstSize()));
                    outShapingPolicy.setAverageBandwidth(outAverageB);
                    outShapingPolicy.setPeakBandwidth(outPeakB);
                    outShapingPolicy.setBurstSize(outBurstS);
                }
                svps.setOutShapingPolicy(outShapingPolicy);

                dpcs.setSetting(svps);
                DVPortConfigSpec[] dpc = {dpcs};
                task = dis.reconfigureDVPort_Task(dpc);
            }
        }
    }
    return task;
}

@Override
public Task cloneTemplate(ServiceInstance si, VcCloneTemplateReq templateReq) throws RemoteException {
    log.info(errorName+"cloneTemplate##VcCloneTemplateReq={}", JSONUtil.toJsonStr(templateReq));
    Datacenter dataCenter = (Datacenter) new InventoryNavigator(si.getRootFolder())
            .searchManagedEntity(VcenterConstantUtils.Vcenter.ManagedEntityType.Datacenter, templateReq.getDcName());
    InventoryNavigator inventoryNavigator = new InventoryNavigator(dataCenter);
    VirtualMachine vm = (VirtualMachine) si.getSearchIndex().findByUuid(dataCenter, templateReq.getServerId(), true,
            false);
    VirtualMachineRelocateSpec virtualMachineRelocateSpec = new VirtualMachineRelocateSpec();
    ComputeResource computerResource = (ComputeResource) inventoryNavigator.searchManagedEntity("ComputeResource",
            templateReq.getClusterName());
    Datastore datastore = (Datastore) inventoryNavigator.searchManagedEntity(VcenterConstantUtils.ManagedEntityType.Datastore,
            templateReq.getDataStoreName());
    if (computerResource.getResourcePool() != null) {
        virtualMachineRelocateSpec.setPool(computerResource.getResourcePool().getMOR());
    }
    virtualMachineRelocateSpec.setDatastore(datastore.getMOR());
    VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
    cloneSpec.setLocation(virtualMachineRelocateSpec);
    cloneSpec.setPowerOn(false);
    cloneSpec.setTemplate(true);
    return vm.cloneVM_Task((Folder) vm.getParent(), templateReq.getName(), cloneSpec);
}

private static List<VirtualDeviceConfigSpec> removeNICDeviceConfigSpecForAll(Datacenter dataCenter,
                                                                             VirtualMachine vm) {
    List<VirtualDeviceConfigSpec> list = new ArrayList<VirtualDeviceConfigSpec>();
    VirtualMachineConfigInfo vmConfigInfo = vm.getConfig();

    VirtualDevice[] VirtualDevices = vmConfigInfo.getHardware().getDevice();

    for (int k = 0; k < VirtualDevices.length; k++) {
        if (VirtualDevices[k] instanceof VirtualEthernetCard) {
            VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
            nicSpec.setOperation(VirtualDeviceConfigSpecOperation.remove);
            VirtualEthernetCard nic = (VirtualEthernetCard) VirtualDevices[k];
            nicSpec.setDevice(nic);
            list.add(nicSpec);
        }
    }
    return list;
}

//检查当前虚机是否有scci控制器
private boolean getVirtualSCSIController(VirtualMachine vm) {
    if (vm != null) {
        VirtualDevice[] devices = vm.getConfig().getHardware().getDevice();
        if (devices != null && devices.length > 0) {
            for (int i = 0; i < devices.length; i++) {
                if (devices[i] instanceof VirtualSCSIController) {
                    return true;
                }
            }
        }
    }
    return false;
}

// 查询模板,全局模板中找
private VirtualMachine getTemplate(ManagedEntity dc, String templateName) throws Exception {
    InventoryNavigator inventoryNavigator = new InventoryNavigator(dc);
    VirtualMachine virtualMachine = (VirtualMachine) inventoryNavigator.searchManagedEntity("VirtualMachine", templateName);
    if (virtualMachine.getConfig().isTemplate()) {
        return virtualMachine;
    }
    throw new Exception("镜像未查询到!!!");
}


@Override
public boolean createVcWithTempate(ServiceInstance si, VcCreateInstanceReq req) {
    log.info(errorName+"createVcWithTempate##VcCreateInstanceReq={}", JSONUtil.toJsonStr(req.toString()));
    try {
        Folder rootFolder = si.getRootFolder();//跟目录
        ManagedEntity dc = new InventoryNavigator(rootFolder).searchManagedEntity("Datacenter", req.getDataCenterName());
        InventoryNavigator inventoryNavigator = new InventoryNavigator(dc);//文件夹目录
        Datacenter datacenter = (Datacenter) dc;
        Folder newFolder = (Folder) inventoryNavigator.searchManagedEntity(ManagedEntityType.Folder, req.getFolderName());;
        if(newFolder == null){
            newFolder = datacenter.getVmFolder().createFolder(req.getFolderName());
        }
        
        String clusterName = req.getCluster();
        String name = req.getVmName();
        String hostName = req.getHost();
        String templateName = req.getTemplateName();//模版

        VirtualMachine templateVM = getTemplate(dc, templateName);
        
      /*  VirtualDevice[] devices = templateVM.getConfig().getHardware().getDevice();
        List<String> removeDiskName = new ArrayList<String>();
        for (int i = 0; devices != null && i < devices.length; i++) {
            if (devices[i] instanceof VirtualDisk) {
                boolean findDiskFlag = false;
                for (int j = 0; j < req.getDiskArray().size(); j++)
                {
                    EditDiskParam disk = req.getDiskArray().get(j);
                    if(devices[i].getDeviceInfo().getLabel().equalsIgnoreCase(disk.getDeviceLabel())){
                        findDiskFlag = true;
                        break;
                    } 
                }
                
                if(!findDiskFlag){
                    removeDiskName.add(devices[i].getDeviceInfo().getLabel());
                }
            }
        } */
        
        VirtualMachineRelocateSpec virtualMachineRelocateSpec = new VirtualMachineRelocateSpec();
        ComputeResource computerResource = (ComputeResource) inventoryNavigator.searchManagedEntity("ComputeResource", clusterName);
        Datastore datastore = (Datastore) inventoryNavigator.searchManagedEntity("Datastore", req.getDataStore());
        if (computerResource.getResourcePool() != null) {
            virtualMachineRelocateSpec.setPool(computerResource.getResourcePool().getMOR());
        }
        virtualMachineRelocateSpec.setDatastore(datastore.getMOR());
        HostSystem hostEntity = (HostSystem) new InventoryNavigator(dc).searchManagedEntity("HostSystem", hostName);
        if (hostEntity != null) {
            virtualMachineRelocateSpec.setHost(hostEntity.getMOR()); // 可以不用setHost
        }

        VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
        configSpec.setName(name); // 设置虚拟机名称
        configSpec.setNumCPUs(req.getCPU());//cpu
        configSpec.setMemoryMB((long) req.getMemory());//内存
        //configSpec.setAlternateGuestName();//镜像
        VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
        cloneSpec.setLocation(virtualMachineRelocateSpec);
        //设置开机
        cloneSpec.setPowerOn(true);
        cloneSpec.setTemplate(false);
        cloneSpec.setConfig(configSpec);

        Task task = templateVM.cloneVM_Task(newFolder, name, cloneSpec);

        vcCreate2(task, req, si);
        return true;
    } catch (Exception e) {
        log.error(errorName+"createVcWithTempate", e);
    }
    return false;
}

public void vcCreate2(Task task, VcCreateInstanceReq req, ServiceInstance si) {
    VmCreateRunnable2 t1 = new VmCreateRunnable2(task, req, si);
    new Thread(t1).start();
}


public static VirtualDeviceConfigSpec createDiskSpec(VirtualMachine vm, String dsName, long diskSizeKB, String diskMode) {
    //虚拟磁盘配置信息
    VirtualDeviceConfigSpec diskSpec = new VirtualDeviceConfigSpec();

    VirtualMachineConfigInfo vmConfig = vm.getConfig();
    VirtualDevice[] vds = vmConfig.getHardware().getDevice();
    //虚拟磁盘相关操作
    diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
    diskSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.create);

    VirtualDisk vd = new VirtualDisk();
    vd.setCapacityInKB(diskSizeKB);
    diskSpec.setDevice(vd);
    int key = 0;
    for (int k = 0; k < vds.length; k++) {
        vd.setKey(k);
        vd.setUnitNumber(k);
        if (vds[k].getDeviceInfo().getLabel().equalsIgnoreCase("SCSI Controller 0")) {
            key = vds[k].getKey();
        }
    }
    vd.setControllerKey(key);

    VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();
    String fileName = "[" + dsName + "]";
    diskfileBacking.setFileName(fileName);
    diskfileBacking.setDiskMode(diskMode);
    diskfileBacking.setThinProvisioned(true);
    vd.setBacking(diskfileBacking);
    return diskSpec;
}


private void createScsiController(VirtualMachine vm) throws Exception {
    VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
    VirtualDeviceConfigSpec diskSpec = new VirtualDeviceConfigSpec();
    diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
    VirtualLsiLogicSASController scsiCtrl = new VirtualLsiLogicSASController();
    scsiCtrl.setBusNumber(0);
    scsiCtrl.setSharedBus(VirtualSCSISharing.noSharing);
    diskSpec.setDevice(scsiCtrl);
    VirtualDeviceConfigSpec[] vdiskSpecArray = {diskSpec};
    vmConfigSpec.setDeviceChange(vdiskSpecArray);
    Task task = vm.reconfigVM_Task(vmConfigSpec);
    task.waitForTask();
}

@Override
public boolean editVc(ServiceInstance si, UpdateInstance req){
    log.info(errorName+"editVc##UpdateInstance={}",JSONUtil.toJsonStr(req));
    Long start = System.currentTimeMillis();
    VcUpdateInstanceParam data = req.getVcUpdateInstance();
    Datacenter dataCenter = getDatacenter(si, data.getDataCenterName());
    try {
        VirtualMachine vm = (VirtualMachine) si.getSearchIndex().findByUuid(dataCenter, data.getServerId(), true, false);
        // 检查当前虚机是否有scsi控制器,如果没有则新增配置
        if (!getVirtualSCSIController(vm)) {
            createScsiController(vm);
        }
        VirtualMachineConfigOption configOption = vm.getEnvironmentBrowser().queryConfigOption(null, null);
        GuestOsDescriptor[] guestOsDescs = configOption.getGuestOSDescriptor();
        
        for (GuestOsDescriptor guestOsDesc : guestOsDescs) {
            if (guestOsDesc.getId().equals(vm.getConfig().getGuestId())) {
                guestOsDesc.getRecommendedEthernetCard();
            }
        }

        
        if(!vm.getRuntime().powerState.name().equals(VirtualMachinePowerState.poweredOff.name())){
            Task task = vm.powerOffVM_Task(); //先关机再设置
            String result = task.waitForTask();
            if (!Task.SUCCESS.equals(result)) {
                return false;
            }
        }
        
        String name = req.getName();//虚机名
        String memory = (data.getMemory() != null && data.getMemory() > 0) ? data.getMemory().toString() : null;//内存
        Integer cpu = data.getCPU();//cpu

        VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
        // 更新名称
        if (StringUtils.isNotBlank(name)) {
            vmConfigSpec.setName(name);
        }
        // 更新内存
        if (StringUtils.isNotBlank(memory)) {
            vmConfigSpec.setMemoryMB(Long.parseLong(memory));
        }
        // 更新CPU
        if (cpu != null && cpu > 0) {
            vmConfigSpec.setNumCPUs(cpu);
        }
        //磁盘操作
        List<VirtualDeviceConfigSpec> vdcsList = dealDisk(vm, data.getDisk());
        //sdk处理
        Task task = vm.reconfigVM_Task(dealVcList(vmConfigSpec, vdcsList));
        String result = task.waitForTask();
        Long end = System.currentTimeMillis();
        log.info(errorName+"editVc##use time ={}",end-start);
        if (!Task.SUCCESS.equals(result)) {
            result = task.waitForTask();
            if(!Task.SUCCESS.equals(result)){
                return false;
            }
        }else {
           //更新成功启动虚拟机
           vm.powerOnVM_Task(null);
        }
        vm.refreshStorageInfo();
        return true;
    }catch (Exception e){
        log.error(errorName+"##editVc", e);
        return false;
    }

}

private List<VirtualDeviceConfigSpec> dealDisk(VirtualMachine vm, VcUpdateInstanceParam.DiskParam disk) throws Exception {
    List<VirtualDeviceConfigSpec> vdcsList = new ArrayList<>();
    if (disk == null) {
        return vdcsList;
    }
    // 1、修改磁盘
    List<VcUpdateInstanceParam.DiskParam.DiskUpdate> updateDisk = disk.getUpdateDisk();
    if (updateDisk != null && updateDisk.size() > 0) {
        for (int i = 0; i < updateDisk.size(); i++) {
            VcUpdateInstanceParam.DiskParam.DiskUpdate diskUpdate = updateDisk.get(i);
            String diskName = diskUpdate.getDiskName();
            Long diskSizeMB = diskUpdate.getDiskSizeMB() * 1024 * 1024;//磁盘前端传gb,转换为kb
            VirtualDeviceConfigSpec vdiskSpec = updateDiskVirtualDeviceConfigSpec(vm, diskName, diskSizeMB);
            if (vdiskSpec != null) {
                vdcsList.add(vdiskSpec);
            }
        }
    }

    //2、 新增磁盘
    List<Integer> addDiskSize = disk.getAddDiskSize();
    if (addDiskSize != null && addDiskSize.size() > 0) {
        for (int i = 0; i < addDiskSize.size(); i++) {
            Integer add = addDiskSize.get(i)*1024;
            VirtualMachineDeviceManager vmdm = new VirtualMachineDeviceManager(vm);
            vmdm.createHardDisk(add, VirtualDiskType.preallocated, VirtualDiskMode.persistent);
        }
    }
    // 3、删除磁盘
    List<String> removeDiskName = disk.getRemoveDiskName();
    if (removeDiskName != null && removeDiskName.size() > 0) {
        VirtualMachineDeviceManager vmdmtwo = new VirtualMachineDeviceManager(vm);
        List<VirtualDevice> devs = new ArrayList<VirtualDevice>();
        for (int i = 0; i < removeDiskName.size(); i++) {
            devs.add(vmdmtwo.findHardDisk(removeDiskName.get(i)));
        }
        vmdmtwo.removeDevices(devs, true);
    }

    return vdcsList;
}


private VirtualMachineConfigSpec dealVcList(VirtualMachineConfigSpec vmConfigSpec, List<VirtualDeviceConfigSpec> list) {
    if (list == null || list.size() <= 0) {
        return vmConfigSpec;
    }
    VirtualDeviceConfigSpec[] vdiskSpecArray = new VirtualDeviceConfigSpec[list.size()];
    for (int i = 0; i < vdiskSpecArray.length; i++) {
        vdiskSpecArray[i] = list.get(i);
    }
    vmConfigSpec.setDeviceChange(vdiskSpecArray);
    return vmConfigSpec;
}


static VirtualDeviceConfigSpec updateNicSpec(ServiceInstance si, String netName, String oldNetname,
                                             VirtualMachine vm, String nicName, String ethernetCardClass, Datacenter dataCenter) throws Exception {
    DistributedVirtualPortgroup dvp = (DistributedVirtualPortgroup) new InventoryNavigator(dataCenter)
            .searchManagedEntity("DistributedVirtualPortgroup", netName);

    VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
    nicSpec.setOperation(VirtualDeviceConfigSpecOperation.edit);

    VirtualEthernetCardDistributedVirtualPortBackingInfo nicBacking = new VirtualEthernetCardDistributedVirtualPortBackingInfo();
    DistributedVirtualSwitchPortConnection dvpc = new DistributedVirtualSwitchPortConnection();
    dvpc.setPortgroupKey(dvp.getKey());
    dvpc.setSwitchUuid(
            (new DistributedVirtualSwitch(si.getServerConnection(), dvp.getConfig().getDistributedVirtualSwitch()))
                    .getUuid());
    nicBacking.setPort(dvpc);

    DistributedVirtualPortgroup olddvp = (DistributedVirtualPortgroup) new InventoryNavigator(dataCenter)
            .searchManagedEntity("DistributedVirtualPortgroup", oldNetname);
    VirtualMachineConfigInfo vmConfigInfo = vm.getConfig();

    VirtualEthernetCard nic = null;
    VirtualDevice[] VirtualDevices = vmConfigInfo.getHardware().getDevice();
    for (int k = 0; k < VirtualDevices.length; k++) {
        if (VirtualDevices[k] instanceof VirtualEthernetCard) {
            if (VirtualDevices[k].getBacking() instanceof VirtualEthernetCardDistributedVirtualPortBackingInfo) {
                if (((VirtualEthernetCardDistributedVirtualPortBackingInfo) VirtualDevices[k].getBacking())
                        .getPort().getPortgroupKey().equalsIgnoreCase(olddvp.getKey())) {
                    nic = (VirtualEthernetCard) VirtualDevices[k];
                }
            }
        }
    }
    nic.setBacking(nicBacking);
    nicSpec.setDevice(nic);
    return nicSpec;
}


static VirtualDeviceConfigSpec createNicSpec(ServiceInstance si, String netName, String nicName,
                                             String ethernetCardClass, Datacenter dataCenter, String fixedIp) throws Exception {
    DistributedVirtualPortgroup dvp = (DistributedVirtualPortgroup) new InventoryNavigator(dataCenter)
            .searchManagedEntity("DistributedVirtualPortgroup", netName);

    VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
    nicSpec.setOperation(VirtualDeviceConfigSpecOperation.add);

    VirtualEthernetCard nic = null;
    if ("".equals(ethernetCardClass)) {
        nic = new VirtualPCNet32();
    } else {
        Class ethernetCard = Class.forName("com.vmware.vim25." + ethernetCardClass);
        nic = (VirtualEthernetCard) ethernetCard.newInstance();
    }

    VirtualEthernetCardDistributedVirtualPortBackingInfo nicBacking = new VirtualEthernetCardDistributedVirtualPortBackingInfo();
    DistributedVirtualSwitchPortConnection dvpc = new DistributedVirtualSwitchPortConnection();
    dvpc.setPortgroupKey(dvp.getKey());
    dvpc.setSwitchUuid(
            (new DistributedVirtualSwitch(si.getServerConnection(), dvp.getConfig().getDistributedVirtualSwitch()))
                    .getUuid());
    nicBacking.setPort(dvpc);

    Description info = new Description();
    info.setLabel(nicName);
    info.setSummary(netName);
    nic.setDeviceInfo(info);
    nic.setAddressType("generated");
    /*if (StringUtils.isBlank(fixedIp)) {
        nic.setAddressType("generated");
    } else {
        nic.setAddressType("manual");
    }*/

    nic.setBacking(nicBacking);
    nic.setKey(0);

    nicSpec.setDevice(nic);
    return nicSpec;
}

private static VirtualDeviceConfigSpec removeNICDeviceConfigSpec(Datacenter dataCenter, VirtualMachine vm,
                                                                 String netname) throws Exception {
    DistributedVirtualPortgroup dvp = (DistributedVirtualPortgroup) new InventoryNavigator(dataCenter)
            .searchManagedEntity("DistributedVirtualPortgroup", netname);
    VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
    VirtualMachineConfigInfo vmConfigInfo = vm.getConfig();

    VirtualEthernetCard nic = null;
    VirtualDevice[] VirtualDevices = vmConfigInfo.getHardware().getDevice();
    nicSpec.setOperation(VirtualDeviceConfigSpecOperation.remove);
    for (int k = 0; k < VirtualDevices.length; k++) {
        if (VirtualDevices[k] instanceof VirtualEthernetCard) {
            if (VirtualDevices[k].getBacking() instanceof VirtualEthernetCardDistributedVirtualPortBackingInfo) {
                if (((VirtualEthernetCardDistributedVirtualPortBackingInfo) VirtualDevices[k].getBacking())
                        .getPort().getPortgroupKey().equalsIgnoreCase(dvp.getKey())) {
                    nic = (VirtualEthernetCard) VirtualDevices[k];
                }
            }
        }
    }
    if (nic != null) {
        nicSpec.setDevice(nic);
    } else {
        return null;
    }
    return nicSpec;
}

private static VirtualDeviceConfigSpec updateDiskVirtualDeviceConfigSpec(VirtualMachine vm, String updateDiskLabel,
                                                                         long updateDiskSizeGB) {
    VirtualDeviceConfigSpec vdcs = new VirtualDeviceConfigSpec();
    VirtualMachineConfigInfo vmci = vm.getConfig();
    VirtualDevice[] devices = vmci.getHardware().getDevice();
    VirtualDisk theDisk = null;
    for (int i = 0; devices != null && i < devices.length; i++) {
        if (devices[i] instanceof VirtualDisk
                && devices[i].getDeviceInfo().getLabel().equalsIgnoreCase(updateDiskLabel)) {
            theDisk = (VirtualDisk) devices[i];
            break;
        }
    }
    // 更改系统磁盘大小
    if (theDisk == null || theDisk.getCapacityInKB() == updateDiskSizeGB) {
        return null;
    }
    theDisk.setCapacityInKB(updateDiskSizeGB);
    vdcs.setDevice(theDisk);
    vdcs.setOperation(VirtualDeviceConfigSpecOperation.edit);
    return vdcs;
}

@Override
public Result<Integer> getRemoteDisplayVncPort(HostSystem host) throws RemoteException {
    List<Integer> allPort = new ArrayList<>();
    for (int i = portStart; i <= portEnd; i++) {
        allPort.add(i);
    }
    int port = 0;
    List<Integer> exsitPort = new ArrayList<Integer>();
    if (host != null) {
        VirtualMachine[] vms = host.getVms();
        for (VirtualMachine v : vms) {
            if (null != v.getConfig()) {
                OptionValue[] optionValues = v.getConfig().getExtraConfig();
                for (OptionValue opt : optionValues) {
                    if (null != opt && "RemoteDisplay.vnc.port".equals(opt.getKey())) {
                        exsitPort.add(Integer.parseInt(opt.getValue().toString()));
                    }
                }
            }
        }
        allPort.removeAll(exsitPort);
        synchronized (this) {
            Random r = new Random();
            port = allPort.get(r.nextInt(allPort.size()));
        }
    }
    return ResultUtil.data(port);
}

@Override
public String getUuidByName(ServiceInstance si, QueryInstanceParam data) {
    log.info(errorName+"getUuidByName##QueryInstanceParam={}",JSONUtil.toJsonStr(data));
    try {
        Datacenter dataCenter = getDatacenter(si, data.getDataCenterName());
        VirtualMachine vm = (VirtualMachine) new InventoryNavigator(dataCenter).searchManagedEntity("VirtualMachine", data.getName());
        return StringUtils.isNotBlank(vm.getSummary().getConfig().getUuid()) ? vm.getSummary().getConfig().getUuid() : null;
    } catch (Exception e) {
        return null;
    }
}

@Override
public List<VcDataCenter> listHostFolder(ServiceInstance si) throws Exception {
    List<VcDataCenter> datacenters = new ArrayList<>();
    ManagedEntity[] dcs = new InventoryNavigator(si.getRootFolder()).searchManagedEntities(VcenterConstantUtils.Vcenter.ManagedEntityType.Datacenter);
    for (int i = 0; i < dcs.length; i++) {
        Datacenter dataCenter = (Datacenter) dcs[i];
        Folder dcFolder = dataCenter.getHostFolder();
        VcDataCenter vc = new VcDataCenter();
        vc.setName(dataCenter.getName());
        vc.setType("Datacenter");
        vc.setHostFolders(new ListTree().getHostFolder(dcFolder));
        datacenters.add(vc);
    }
    return datacenters;
}

@Override
public List<VcDataStore> queryHostDataStore(ServiceInstance si, VcDataStoreModelReq vcDataStoreInfo)throws Exception{
    log.info(errorName+"queryHostDataStore##VcDataStoreModelReq={}",JSONUtil.toJsonStr(vcDataStoreInfo));
    List<VcDataStore> list = new ArrayList<>();
    Folder rootFolder = si.getRootFolder();
    Datastore[] datastores = null;
    Datacenter dc = (Datacenter) new InventoryNavigator(rootFolder).searchManagedEntity("Datacenter", vcDataStoreInfo.getDcName());
    if (null != vcDataStoreInfo.getClusterName()) {
        //选择数据中心和集群,查询集群下存储
        ClusterComputeResource cluster = (ClusterComputeResource) new InventoryNavigator(dc).searchManagedEntity("ClusterComputeResource", vcDataStoreInfo.getClusterName());
        if (null != vcDataStoreInfo.getHostName()) { //选择数据中心和集群、主机,查询主机下存储
            HostSystem host = (HostSystem) new InventoryNavigator(cluster).searchManagedEntity("HostSystem", vcDataStoreInfo.getHostName());
            datastores = host.getDatastores();
        } else {
            datastores = cluster.getDatastores();
        }
    } else {
        HostSystem host = (HostSystem) new InventoryNavigator(dc).searchManagedEntity("HostSystem", vcDataStoreInfo.getHostName());
        datastores = host.getDatastores();
    }

    for (int i = 0; i < datastores.length; i++) {
        try {
            boolean isSsd = false;
            Datastore datastore = (Datastore) datastores[i];
            DatastoreInfo datastoreInfo = datastore.getInfo();
            if (datastoreInfo instanceof VmfsDatastoreInfo) {
                VmfsDatastoreInfo info = (VmfsDatastoreInfo) datastore.getInfo();
                isSsd = info.getVmfs().getSsd();
            }
            VcDataStore vd = new VcDataStore();
            vd.setName(datastore.getName());
            vd.setFreeSpace(Math.round(datastore.getSummary().getFreeSpace() * 100 / 1024 / 1024 / 1024) / 100.0);
            vd.setType(datastore.getSummary().getType());
            vd.setStatus(datastore.getOverallStatus().name());
            vd.setProvisioningSupported(datastore.getCapability().perFileThinProvisioningSupported);
            vd.setCapacity(Math.round(datastore.getSummary().getCapacity() * 100 / 1024 / 1024 / 1024) / 100.0);
            vd.setSsd(isSsd);
            list.add(vd);
        }catch (Exception e){
            log.error(errorName+"queryHostDataStore", e);
        }
    }
    return list;
}



@Override
public Result<String> migrateVM(ServiceInstance si, VcMigrateReq vcDataStoreInfo) {
    log.info(errorName+"migrateVM##VcMigrateReq={}",JSONUtil.toJsonStr(vcDataStoreInfo));
    Task task = null;
    try {
        Folder rootFolder = si.getRootFolder();
        Datacenter dc = (Datacenter) new InventoryNavigator(rootFolder).searchManagedEntity("Datacenter",
                vcDataStoreInfo.getDcName());
        VirtualMachine vm = (VirtualMachine) new InventoryNavigator(
                rootFolder).searchManagedEntity(
                "VirtualMachine", vcDataStoreInfo.getVmName());
        if (vm == null) {
            return ResultUtil.error("虚拟机不存在.");
        }
        if (vcDataStoreInfo.getMigrateType() == 2) {
            VirtualMachineRelocateSpec vmr = new VirtualMachineRelocateSpec();
            Datastore datastore = getDatastoreByName(dc, vcDataStoreInfo.getDataStore());
            vmr.setDatastore(datastore.getMOR());
            task = vm.relocateVM_Task(vmr);
        } else {
            ClusterComputeResource cluster = (ClusterComputeResource) new InventoryNavigator(dc)
                    .searchManagedEntity("ClusterComputeResource", vcDataStoreInfo.getClusterName());
            HostSystem newHost = (HostSystem) new InventoryNavigator(cluster).searchManagedEntity("HostSystem",
                    vcDataStoreInfo.getHostName());
            if (newHost == null) {
                return ResultUtil.error("主机不存在.");
            }
           /* String[] checks = new String[]{"cpu", "software"};
            HostVMotionCompatibility[] vmcs =
                    si.queryVMotionCompatibility(vm, new HostSystem[]
                            {newHost}, checks);
            String[] comps = vmcs[0].getCompatibility();
            if (comps == null || checks.length != comps.length) {
                si.getServerConnection().logout();
                return ResultUtil.error("CPU或者软件不匹配.");
            }*/

            if (vcDataStoreInfo.getMigrateType() == 1) {

                HostSystem oldHost = new HostSystem(vm.getServerConnection(), vm.getRuntime().getHost());
                if (oldHost.getName().equals(vcDataStoreInfo.getHostName())) {
                    return ResultUtil.error("虚拟机已经在此主机上运行");
                }
                VirtualMachineRelocateSpec vmr = new VirtualMachineRelocateSpec();

                if (vm.getDatastores().length > 1) {
                    return ResultUtil.error("存储不兼容,无法迁移主机");
                }
                Datastore datastore = getDatastoreByName(dc, vm.getDatastores()[0].getName());
                if (datastore == null) {
                    return ResultUtil.error(String.format("无法访问该云主机的存储 [%s]", vm.getDatastores()[0].getName()));
                }
                vmr.setDatastore(datastore.getMOR());
                if (newHost != null) {
                    vmr.setHost(newHost.getMOR());
                }
                vmr.setPool(cluster.getResourcePool().getMOR());
                task = vm.relocateVM_Task(vmr, VirtualMachineMovePriority.highPriority);
            } else if (vcDataStoreInfo.getMigrateType() == 3) {
                VirtualMachineRelocateSpec vmr = new VirtualMachineRelocateSpec();
                Datastore datastore = getDatastoreByName(dc, vcDataStoreInfo.getDataStore());
                vmr.setDatastore(datastore.getMOR());
                if (newHost != null) {
                    vmr.setHost(newHost.getMOR());
                }
                vmr.setPool(cluster.getResourcePool().getMOR());
                task = vm.relocateVM_Task(vmr, VirtualMachineMovePriority.highPriority);
            }
        }

        TaskInfo taskInfo = task.getTaskInfo();
        Thread.sleep(20000);
        log.info("迁移主机结果 :{}", JSONUtil.parse(taskInfo));
        if (taskInfo != null) {
            if (TaskInfoState.error.name().equals(taskInfo.state.name())) {
                log.error("迁移任务错误信息 :{}", task.getTaskInfo().error.localizedMessage);
                if (task.getTaskInfo().error.localizedMessage.contains("Unable to access file ")) {
                    return ResultUtil.error("无法访问该云主机的存储文件");
                }
                return ResultUtil.error(String.format("迁移失败:%s", task.getTaskInfo().error.localizedMessage));
            }
            if (TaskInfoState.running.name().equals(taskInfo.state.name()) || TaskInfoState.queued.name().equals(taskInfo.state.name())) {
                return ResultUtil.data(task.getTaskInfo().key);
            }
        }

    } catch (Exception ex) {
        log.error(errorName+"migrateVM",ex);
        return ResultUtil.error("迁移异常");
    } finally {
        si.getServerConnection().logout();
    }

    return ResultUtil.data("success");
}


/**==============================================分割线===========================================================*/

@Override
public Result<CloudResultResource> createExtend(ServiceInstance si, BaseCloudParams<CreateInstanceParams> baseCloudParams) {
    //创建vm虚拟机
    CreateInstanceParams data = baseCloudParams.getData();
    VcCreateInstanceReq vcCreateInstanceReq = new VcCreateInstanceReq();

    vcCreateInstanceReq.setDataCenterName(data.getDataCenterName());
    vcCreateInstanceReq.setCluster(data.getClusterName());
    vcCreateInstanceReq.setHost(data.getHost());
    vcCreateInstanceReq.setDataStore(data.getDataStore());
    vcCreateInstanceReq.setGuestOsId(data.getGustOsId());
    //网卡
    if (data.getNics()!=null && data.getNics().size() > 0) {
        vcCreateInstanceReq.setNet(data.getNics().get(0).getSubnetId());
    }
    vcCreateInstanceReq.setCPU(data.getCpu());
    vcCreateInstanceReq.setMemory(data.getMemory());
    vcCreateInstanceReq.setTemplateName(data.getImageRef());
    vcCreateInstanceReq.setFolderName(data.getFolderName()); 
    
    //系统盘
    VcCreateInstanceReq.EditDiskParam hardDisk = new VcCreateInstanceReq.EditDiskParam();
   // hardDisk.setDeviceLabel((StringUtils.contains(data.getRootVolume().getType(), "system")) ? "Hard disk 1" : "system");
    hardDisk.setDeviceLabel("Hard disk 1");
    hardDisk.setDeviceValueKB(Long.valueOf(data.getRootVolume().getSize()*1024*1024));
    List<VcCreateInstanceReq.EditDiskParam> systemDisk = new ArrayList<>();
    systemDisk.add(hardDisk);
    vcCreateInstanceReq.setDiskArray(systemDisk);
    //数据盘
    if (data.getDataVolumes() != null && data.getDataVolumes().size() > 0) {
        List<VcCreateInstanceReq.AddDiskParam> dataDiskArr = new ArrayList<>();
        data.getDataVolumes().forEach(info -> {
            VcCreateInstanceReq.AddDiskParam dataDisk = new VcCreateInstanceReq.AddDiskParam();
            dataDisk.setMemValue(info.getSize()*1024);
            dataDiskArr.add(dataDisk);
        });
        vcCreateInstanceReq.setNewdiskArray(dataDiskArr);
    }

    CloudResultResource cloudResultResource = null;
    for(int i=0;i<data.getCount();i++){
        String uuid = UUID.randomUUID().toString();
        String vmname = data.getName() + "-"+ UUID.randomUUID().toString().substring(0,8);
        vcCreateInstanceReq.setVmName(vmname);
        boolean vmResult = false;
        if(StringUtils.isNotBlank(vcCreateInstanceReq.getTemplateName())){//从模版创建虚拟机
            vmResult = this.createVcWithTempate(si,vcCreateInstanceReq);
        }else{ // 创建裸机
            vmResult = this.createVirtualMachine(si, vcCreateInstanceReq);
        }
        
        if (vmResult) {
            this.insert(uuid,vmname,baseCloudParams);
            cloudResultResource = CloudResultResource.setCloudResoure(cloudResultResource,uuid , vmname);
        }
    }

    //同步网络
    if (data.getNics() != null && !data.getNics().isEmpty()) {
        String networkId = data.getNics().get(0).getSubnetId();
        CloudNetwork cloudNetwork = cloudNetworkMapper.selectByPrimaryKey(networkId);
        if(null != cloudNetwork) {
            Integer num1 = (StringUtils.isBlank(cloudNetwork.getNetworkType()) ? 0 : Integer.valueOf(cloudNetwork.getNetworkType())) + data.getCount();
            cloudNetwork.setNetworkType(num1 + "");
            cloudNetworkMapper.updateByPrimaryKeySelective(cloudNetwork);
            log.info(errorName+"createExtend##update network success##num={}",num1);
        }
    }

    this.send2Redis(cloudResultResource.getResources().stream().map(Resources::getId).collect(Collectors.toList()));
    cloudResultResource.setSend(false);
    return ResultUtil.data(cloudResultResource);
}

@Override
public Result<CloudResultResource> editExtend(ServiceInstance si, BaseCloudParams<UpdateInstance> baseCloudParams) {
    UpdateInstance data = baseCloudParams.getData();
    if(!this.editVc(si, data)){
        return ResultUtil.error(ResultTipsEnums.ERROR_UPDATE.getMsg());
    }
    try {
        //更新
        this.updateEcs(si, baseCloudParams);
        CloudResultResource cloudResultResource = CloudResultResource.setCloudResoure(null, data.getVcUpdateInstance().getServerId(), data.getName());
        //更新订单
        Long time = System.currentTimeMillis() + 12*60*1000;
        String uuid = data.getVcUpdateInstance().getServerId()+"--"+time.toString();
        log.info(errorName+"editExtend##update_order##uuid={}",uuid);
    //    redisTemplate.opsForList().leftPush(EcsStatusEnums.VM_UODATE_ORDER.getKey(), uuid);
        return ResultUtil.data(cloudResultResource);
    }catch (Exception e){
        log.error(errorName+"editExtend",e);
        return ResultUtil.error(ResultTipsEnums.ERROR_UPDATE.getMsg());
    }
}

@Override
public Result<CloudResultResource> actionExtend(ServiceInstance si, BaseCloudParams<InstanceActionParams> baseCloudParams) {
    log.info(errorName+"actionExtend##BaseCloudParams={}",JSONUtil.toJsonStr(baseCloudParams));
    InstanceActionParams data = baseCloudParams.getData();
    String key = data.getKey();
    try {
        String id = data.getServerIds().get(0);
        CloudInstance cloudInstance = cloudInstanceMapper.selectByPrimaryKey(id);

        UniInstance uniInstance = JSONUtil.toBean(this.getJsonDetail(cloudInstance, "detail"), UniInstance.class);
        String dataCenterName = uniInstance.getDataCenterName();
        String name = cloudInstance.getInstanceName();

        VcActionRequestParam request = new VcActionRequestParam();
        request.setAction(key);
        request.setServerId(id);
        request.setVmName(name);
        request.setVmPathName(uniInstance.getPathName());
        request.setVcenterName(dataCenterName);
        //1、sdk
        if(!this.dovcAction(si, request)){
            return ResultUtil.error(ResultTipsEnums.ERROR_OPTION.getMsg());
        }
        //2、更新
        String statusName = EcsActionEnums.getStatusName(key);
        cloudInstance.setStatus(statusName);
        cloudInstance.setPowerState(StatusConsts.BYTE_ONE);

        if(StringUtils.contains(key,"delete")){
            cloudInstance.setDeleted(StatusConsts.DELETE_BYTE_ONE);
        }
        cloudInstanceMapper.updateByPrimaryKeySelective(cloudInstance);
        //3、同步
        cloudSyncInvoke.invokeVcenterEcsJob(cloudInstance.getPlatformAuthId(),id,dataCenterName,20,true);
        return ResultUtil.data(CloudResultResource.setCloudResoure(null,id , name));

    }catch (Exception e){
        log.error(errorName+"actionExtend",e);
        return ResultUtil.error(ResultTipsEnums.ERROR_OPTION.getMsg());
    }



}

@Override
public Result<CloudResultResource> trafficShapingExtend(ServiceInstance si, BaseCloudParams<VcTrafficShappingReq> baseCloudParams) {
    log.info(errorName+"trafficShapingExtend##BaseCloudParams={}",JSONUtil.toJsonStr(baseCloudParams));
    VcTrafficShappingReq data = baseCloudParams.getData();
    try {
        List<String> nets = data.getNets();
        Task task = null;
        for (String net : nets) {
            task = this.trafficShaping(si, data, net);
            Thread.sleep(1000);
        }
        if (null!=task  && task.getTaskInfo().getState().toString().equals("error")) {
            return  ResultUtil.error(ResultTipsEnums.ERROR_OPTION.getMsg());
        }
        return ResultUtil.data(null);
    }catch (Exception e){
        log.error(errorName+"trafficShapingExtend", e);
        return ResultUtil.error(ResultTipsEnums.ERROR_OPTION.getMsg());
    }

}

@Override
public Result<CloudResultResource> cloneTemplateExtend(ServiceInstance si, BaseCloudParams<VcCloneTemplateReq> baseCloudParams) {
    log.info(errorName+"cloneTemplateExtend##BaseCloudParams={}",JSONUtil.toJsonStr(baseCloudParams));
    VcCloneTemplateReq data = baseCloudParams.getData();
    try {
        Task task =  this.cloneTemplate(si,data);
        if (task != null && task.getTaskInfo().getState().toString().equals("error")) {
            return ResultUtil.error(ResultTipsEnums.ERROR_OPTION.getMsg());
        }
        return ResultUtil.data(null);
    }catch (Exception e){
        log.error(errorName+"cloneTemplateExtend", e);
        return ResultUtil.error(ResultTipsEnums.ERROR_OPTION.getMsg());
    }
}

@Override
public Result<String> migrateVMExtend(ServiceInstance si, BaseCloudParams<VcMigrateReq> baseCloudParams) {
    Result<String> res = this.migrateVM(si, baseCloudParams.getData());
    if(!res.isSuccess()){
        return ResultUtil.error(ResultTipsEnums.ERROR_MOVE.getMsg());
    }
    return ResultUtil.data(res.getResult());
}

private Integer updateEcs(ServiceInstance si, BaseCloudParams<UpdateInstance> baseCloudParams){
    //入库
    try {
        UpdateInstance data = baseCloudParams.getData();
        CloudInstance instance = cloudInstanceMapper.selectByPrimaryKey(data.getVcUpdateInstance().getServerId());
        if(null == instance){
            log.info(errorName+"updateEcs##instance = null");
            return -1;
        }
        CreateInstanceParams createInstanceParams = JSONUtil.toBean(this.getJsonDetail(instance, "info"), CreateInstanceParams.class);
        UniInstance uniInstance = JSONUtil.toBean(this.getJsonDetail(instance, "detail"), UniInstance.class);
        instance.setUpdatedTime(new Date());
        instance.setStatus( EcsActionEnums.getStatusName("updating"));
        //更新detail
        if(StringUtils.isNotBlank(data.getName())){
            createInstanceParams.setName(data.getName());
        }
        if(data.getVcUpdateInstance().getCPU()!=null &&data.getVcUpdateInstance().getCPU()>0){
            createInstanceParams.setCpu(data.getVcUpdateInstance().getCPU());
        }
        if(data.getVcUpdateInstance().getMemory()!=null &&data.getVcUpdateInstance().getMemory()>0){
            createInstanceParams.setMemory(data.getVcUpdateInstance().getMemory());
        }
        if(data.getVcUpdateInstance().getBandwidth()!=null){
            createInstanceParams.setBandwidth(data.getVcUpdateInstance().getBandwidth());
        }
        if(data.getVcUpdateInstance().getRootVolume()!=null){
            createInstanceParams.setRootVolume(data.getVcUpdateInstance().getRootVolume());
        }
        if(data.getVcUpdateInstance().getDataVolumes()!=null&&data.getVcUpdateInstance().getDataVolumes().size()>0){
            createInstanceParams.setDataVolumes(data.getVcUpdateInstance().getDataVolumes());
        }

        if(StringUtils.isNotBlank(data.getInstanceName()) && StringUtils.isNotBlank(createInstanceParams.getFlavorRef())){
            createInstanceParams.setFlavorRef(data.getInstanceName());
        }
        VcUpdateInstanceParam vcUpdateInstanceParam = data.getVcUpdateInstance();
        Datacenter dataCenter = getDatacenter(si, vcUpdateInstanceParam.getDataCenterName());
        VirtualMachine vm = (VirtualMachine) si.getSearchIndex().findByUuid(dataCenter, vcUpdateInstanceParam.getServerId(), true, false);
        JSONObject jsonObject = this.getVmInstance(si, vm, vcUpdateInstanceParam.getDataCenterName());
        if(null != jsonObject.get("disks")) {
            uniInstance.setDisk(jsonObject.get("disks").toString());
        }
        
        cn.hutool.json.JSONObject js = new cn.hutool.json.JSONObject();
        js.put("info",createInstanceParams);
        js.put("detail",uniInstance);
        instance.setDetail(js);
        log.info(errorName+"update##instance={}",JSONUtil.toJsonStr(instance));
        //同步
        cloudSyncInvoke.invokeVcenterEcsJob(baseCloudParams.getPlatformId(),data.getVcUpdateInstance().getServerId(), data.getVcUpdateInstance().getDataCenterName(),60,true);
        return cloudInstanceMapper.updateByPrimaryKeySelective(instance);
    }catch (Exception e){
        log.error(errorName+"update",e);
        return -1;
    }
}

/**
 * 获取detail中的info或detail
 */
private JSONObject getJsonDetail(CloudInstance instance,String str){
    JSONObject detail = JSONUtil.parseObj(instance.getDetail());
    return detail.getJSONObject(str);
}

private int insert(String uuid,String name,BaseCloudParams<CreateInstanceParams> baseCloudParams){
    CreateInstanceParams data = baseCloudParams.getData();
    CloudInstance instance = new CloudInstance();
    instance.setInstanceUuid(uuid);
    instance.setInstanceName(name);
    instance.setCreateUserId(Long.valueOf(baseCloudParams.getUserId()));
    instance.setFlavorVcpu(data.getCpu());
    instance.setFlavorRam(data.getMemory());
    instance.setPlatformAuthId(baseCloudParams.getPlatformId());
    instance.setCloudRegionId(baseCloudParams.getRegionId());
    instance.setPowerState(StatusConsts.BYTE_ONE);
    instance.setStatus(MiddleStateEnum.CREATING.getKey());
    instance.setDeleted(StatusConsts.DELETE_BYTE_ZERO);
    instance.setFlavorName(data.getOsName());
    instance.setCreatedTime(new Date());
    instance.setImageUuid(data.getImageUuid());
    instance.setCloudProjectId(data.getFolderUuid());
    instance.setHypervisorName(data.getHostName());
    instance.setHypervisorUuid(data.getHostUuid());
    data.setHost(data.getHostName());
    cn.hutool.json.JSONObject info = new cn.hutool.json.JSONObject();
    //表单信息
    info.put("info",data);
    instance.setDetail(info);
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    int i = -1;
    try {
        instance.setExpirationTime(formatter.parse(data.getExpirationTime()));
        i = cloudInstanceMapper.insertSelective(instance);
        log.info(errorName+"insert##instance creating={}",name);
    }catch (Exception e){
        log.error(errorName+"insert",e);
    }
    return i;
}


public int getRemoteDisplayVncPort(VirtualMachine vm) throws RemoteException {
    VirtualMachineRuntimeInfo runtime = vm.getRuntime();
    List<Integer> allPort = new ArrayList<>();
    for (int i = portStart; i <= portEnd; i++) {
        allPort.add(i);
    }
    int port = 0;
    List<Integer> exsitPort = new ArrayList<>();
    if (runtime != null) {
        ManagedObjectReference host = runtime.getHost();
        if (host != null) {
            HostSystem h = new HostSystem(vm.getServerConnection(), host);
            VirtualMachine[] vms = h.getVms();
            for (VirtualMachine v : vms) {
                if (v.getConfig() == null) {
                    break;
                }
                OptionValue[] optionValues = v.getConfig().getExtraConfig();
                for (OptionValue opt : optionValues) {
                    if ("RemoteDisplay.vnc.port".equals(opt.getKey())) {
                        exsitPort.add(Integer.parseInt(opt.getValue().toString()));
                    }
                }
            }
            allPort.removeAll(exsitPort);
            synchronized (this) {
                Random r = new Random();
                port = allPort.get(r.nextInt(allPort.size()));
            }
        }
    }
    return port;
}

//获取Datacenter
private Datacenter getDatacenter(ServiceInstance si, String vcenterName) {
    try {
        Folder rootFolder = si.getRootFolder();
        return (Datacenter) new InventoryNavigator(rootFolder).searchManagedEntity(VcenterConstantUtils.Vcenter.ManagedEntityType.Datacenter, vcenterName);
    } catch (Exception e) {
        throw new CloudResourcesException(CloudResourcesErrorEnum.VCENTER_AUTH_ERROR);
    }
}

//按serverId获取vm
private VirtualMachine getVirtualMachine(ServiceInstance si, Datacenter dataCenter, String serverId) {
    try {
        return (VirtualMachine) si.getSearchIndex().findByUuid(dataCenter, serverId, true, false);
    } catch (Exception e) {
        throw new CloudResourcesException(CloudResourcesErrorEnum.VCENTER_AUTH_ERROR);
    }
}


/**
 * vcenter虚机查询
 *
 * @param si
 * @param queryInstanceParam
 * @return
 */
@Override
public List<UniInstance> listVm(ServiceInstance si, QueryInstanceParam queryInstanceParam) {
    log.info(errorName+"listVm##QueryInstanceParam={}" ,JSONUtil.toJsonStr(queryInstanceParam));
    try {
        JSONArray json = arrayVm(si, queryInstanceParam);
        return changeUniInstanceList(json);
    } catch (Exception e) {
        log.error(errorName+"listVm",e);
        throw new CloudResourcesException(VcenterServiceErrorEnum.QUERY_ERROR);
    }
}

/**
 * 按虚机id查询虚机详情
 */
@Override
public UniInstance get(ServiceInstance si, QueryInstanceParam data) {
    try {
        Datacenter dataCenter = getDatacenter(si, data.getDataCenterName());
        
        ManagedEntity vmEntity =  si.getSearchIndex().findByUuid(dataCenter, data.getId(), true, false);
        VirtualMachine vm = (VirtualMachine) vmEntity;
        JSONArray jsonA = new JSONArray();
        JSONObject vmInstance = this.getVmInstance(si, vm, data.getDataCenterName());
        vmInstance.put("dataCenter", dataCenter.getName());
        vmInstance.put("dataCenterUuid", dataCenter.getMOR().get_value());
        VirtualMachineRuntimeInfo runtime = vm.getRuntime();
        ManagedObjectReference host = runtime.getHost();
          if (host != null) {
              HostSystem host1 = new HostSystem(si.getServerConnection(), host);
              vmInstance.put("host",host1.getName());
              vmInstance.put("hostUuid",host1.getHardware().getSystemInfo().getUuid());
              ManagedEntity cluster =getTypeFromParentEntity(host1,"ClusterComputeResource");
              if(cluster != null){ // 防止生产环境数据异常,查不到集群报错
            	  vmInstance.put("cluster",cluster.getName());
	              vmInstance.put("clusterUuid",cluster.getMOR().get_value());
                
              }
             
          }
       
        jsonA.add(vmInstance);
        List<UniInstance> list = changeUniInstanceList(jsonA);
        return (list != null && list.size() > 0) ? list.get(0) : null;
    } catch (Exception e) {
        log.error(errorName+"get",e);
        throw new CloudResourcesException(VcenterServiceErrorEnum.QUERY_ERROR);
    }
}


/**
 * vcenter虚机列表数据转换
 *
 * @param json
 * @return
 */
private List<UniInstance> changeUniInstanceList(JSONArray json) {
    List<UniInstance> list = new ArrayList<>();
    if (json != null && json.size() > 0) {
        for (int i = 0; i < json.size(); i++) {
            UniInstance uniInstance = InstanceBuilder.buildUniInstance(json.getJSONObject(i));
            if (uniInstance != null) {
                list.add(uniInstance);
            }
        }
    }
    log.info("虚机列表:" + JSONUtil.toJsonStr(list));
    return list;
}

/**
 * 获取vcenter虚机列表
 *
 * @param si
 * @return
 */
public JSONArray arrayVm(ServiceInstance si, QueryInstanceParam data) throws Exception {
    JSONArray jsonA = new JSONArray();
    ManagedEntity[] dataCenters=new ManagedEntity[] {};
    String dcName=data.getDataCenterName();
    if(StringUtils.isNotEmpty(dcName)) {
    	 dataCenters[0]=getDatacenter(si,dcName );
    }else {
    	dataCenters = new InventoryNavigator(si.getRootFolder()).searchManagedEntities(CloudCodeConstant.DATACENTER);
    }
    for(ManagedEntity dataCenter:dataCenters) {
    	Datacenter dataCenterv=(Datacenter)dataCenter;
    	 //ManagedEntity[] clusters = new InventoryNavigator(dataCenter).searchManagedEntities(CloudCodeConstant.CLUSTER_COMPUTE_RESOURCE);
         //if (clusters != null && clusters.length > 0) {
             //for (ManagedEntity cluster : clusters) {
                 //System.out.println(cluster.getName());
                 //ClusterComputeResource cluster1 = (ClusterComputeResource)cluster;
                 ManagedEntity[] hosts = new InventoryNavigator(dataCenter).searchManagedEntities(CloudCodeConstant.HOST_SYSTEM);
                 for (ManagedEntity host : hosts) {
                     //System.out.println("-"+host.getName());
                     HostSystem host1 = (HostSystem) host;
                     ManagedEntity cluster =getTypeFromParentEntity(host,"ClusterComputeResource");
                     ManagedEntity[] ens = new InventoryNavigator(host1).searchManagedEntities(CloudCodeConstant.VIRTUAL_MACHINE);
                     for (ManagedEntity en : ens) {
                         VirtualMachine vm = (VirtualMachine) en;
                         //System.out.println("--"+vm.getName());
                         JSONObject vmInstance = this.getVmInstance(si, vm, data.getDataCenterName());
                         //vmInstance.put("cluster", cluster.getName());
                         //vmInstance.put("clusterId", cluster.getMOR().get_value());
	        			if(cluster != null){ // 防止生产环境数据异常,查不到集群报错
	        				  vmInstance.put("cluster",cluster.getName());
                             vmInstance.put("clusterUuid",cluster.getMOR().get_value());
                           
	        			}
                         vmInstance.put("dataCenter", dataCenterv.getName());
                         vmInstance.put("dataCenterUuid", dataCenterv.getMOR().get_value());
                         vmInstance.put("host",host.getName());
                         vmInstance.put("hostUuid",host1.getHardware().getSystemInfo().getUuid());
                         jsonA.add(vmInstance);
                     }
                 }
            // }
         //}
    }       
    
    return jsonA;
}

ManagedEntity getTypeFromParentEntity(ManagedEntity me, String targetType) {
    try {
        if (targetType.equals(me.getParent().getMOR().getType())) {
            return me.getParent();
        } else {
            return getTypeFromParentEntity(me.getParent(), targetType);
        }
    } catch (Exception e) {
        log.error(errorName + "getTypeFromParent", e);
    }
    return null;
}


private JSONObject getVmInstance(ServiceInstance si, VirtualMachine vm, String dataCenterName) throws Exception {
    JSONObject json = new JSONObject();
    VirtualMachineConfigInfo vmconfig=vm.getConfig();
    if (vm != null && vmconfig != null && !vmconfig.isTemplate()) {
    	
    	
        json.put("name", vm.getName());
        //存储
        Datastore[] datastores = vm.getDatastores();
        List<String> dataStoreIds=new ArrayList<String>();
        
        for(Datastore datastore:datastores) {
        	dataStoreIds.add(datastore.getMOR().get_value());
        }
        json.put("dataStoreIds", dataStoreIds);
        if(null!=datastores && datastores.length>0){
            String dataStoreName = datastores[0].getName();
            
            json.put("dataStoreName", dataStoreName);
        }
        
        StringBuilder path=getPath(vm);
        
        
        json.put("path", path.toString());
        json.put("dataCenter", dataCenterName);
        
        json.put("overallStatus", vm.getOverallStatus());
        VirtualMachineSummary sum = vm.getSummary();
        if (sum != null) {
        	VirtualMachineGuestSummary guestSummary=sum.getGuest();
            json.put("ip", guestSummary.getIpAddress());
            if(null!=guestSummary.getToolsStatus()) {
            	json.put("toolsStatus", guestSummary.getToolsStatus().name());
            }
            
            VirtualMachineConfigSummary config = sum.getConfig();
            if (config != null) {
                json.put("uuid", config.getUuid());
                json.put("instanceUuid", config.getInstanceUuid());
                json.put("name", config.getName());
                json.put("annotation", config.getAnnotation());
                json.put("cpu", config.getNumCpu());
                json.put("memory", config.getMemorySizeMB());
                json.put("guestId", config.getGuestId());
                json.put("guestFullName", config.getGuestFullName());
                json.put("vmPathName", config.getVmPathName());
            }
           
            VirtualMachineStorageSummary storage = sum.getStorage();
            if (storage != null) {
                json.put("storageCommitted", Math.round(storage.getCommitted() * 100 / 1024 / 1024 / 1024) / 100.0);
                json.put("storage", Math.round((storage.getCommitted() + storage.getUncommitted()) * 100 / 1024 / 1024 / 1024) / 100.0);
            }
        }

        // 磁盘
        List<Map<String, Object>> diskList = new ArrayList<Map<String, Object>>();
        VirtualDevice[] vds = vmconfig.getHardware().getDevice();
        // 当前虚拟机的mac地址
        List<String> macList = new ArrayList<>();
        if (vds != null && vds.length > 0) {
            for (int i = 0; vds != null && i < vds.length; i++) {
                if (vds[i] instanceof VirtualDisk) {
                    JSONObject disk = new JSONObject();
                    VirtualDisk theDisk = (VirtualDisk) vds[i];
                    disk.put("unitNumber", theDisk.getUnitNumber());
                    disk.put("capacityInKB", theDisk.getCapacityInKB());
                    disk.put("label", theDisk.getDeviceInfo().getLabel());
                    disk.put("diskId", theDisk.getDiskObjectId());
                    diskList.add(disk);
                } else if (vds[i] instanceof VirtualEthernetCard) {
                    VirtualEthernetCard virtualEthernetCard = (VirtualEthernetCard) vds[i];
                    macList.add(virtualEthernetCard.getMacAddress());
                }
            }
        }
        
       
        json.put("disks", diskList);

// String ips = “”;
// GuestInfo guest = vm.getGuest();
// if (guest != null) {
// if (guest.getIpAddress() == null) {
// json.put(“ips”, ips);
// } else {
// json.put(“ips”, guest.getIpAddress());
// }
// }

        // network
        JSONArray netList = new JSONArray();
        Network[] networks = vm.getNetworks();
        json.put("network", "--");
        if (networks != null && networks.length > 0) {
            for (Network net : networks) {
                netList.add(net.getMOR().get_value());
            }
            json.put("network", networks[0].getName());
        }
        json.put("nets", netList);
        
        VirtualMachineRuntimeInfo runtime = vm.getRuntime();
        if (runtime != null) {
        	json.put("connectState", runtime.getConnectionState());
            json.put("powerState", runtime.getPowerState());

// ManagedObjectReference host = runtime.getHost();
// if (host != null) {
// HostSystem h = new HostSystem(si.getServerConnection(), host);
// json.put(“host”, h.getName());
// json.put(“hostUuid”, h.getHardware().getSystemInfo().getUuid());
// }

        }
       
    }
    return json;
}


private static StringBuilder getPath(ManagedEntity en) {
	StringBuilder path=new StringBuilder();
	ManagedEntity parent=en.getParent();
	String name=parent.getName();
	if(!"vm".equals(name)) {
		path.append("/");
		path.append(name);
		return path.append(getPath(parent));
	}
	return path;
}
/**
 * 获取vcenter虚机列表
 *
 * @param si
 * @return
 */
public List<UniInstance> allVm(ServiceInstance si) throws Exception {
    Folder rootFolder = si.getRootFolder();
    List<UniInstance> listRet = new ArrayList<>();
    ManagedEntity[] ens = new InventoryNavigator(rootFolder).searchManagedEntities(VcenterConstantUtils.Vcenter.ManagedEntityType.VirtualMachine);
    for (ManagedEntity en : ens) {
        UniInstance ui = new UniInstance();
        VirtualMachine vm = (VirtualMachine) en;
        VirtualMachineConfigInfo vmconfig=vm.getConfig();
        if (vm != null && vmconfig != null && !vmconfig.isTemplate()) {
            ui.setName(vm.getName());
            ui.setStatus(String.valueOf(vm.getOverallStatus()));
            VirtualMachineSummary sum = vm.getSummary();
            if (sum != null) {
                VirtualMachineConfigSummary config = sum.getConfig();
                if (config != null) {
                    ui.setId(config.getUuid());
                    ui.setHost(config.getInstanceUuid());
                    ui.setName(config.getName());
                    ui.setVcpus(String.valueOf(config.getNumCpu()));
                    ui.setRam(String.valueOf(config.getMemorySizeMB()));
                    ui.setInstanceTypeId(config.getGuestId());
                    ui.setInstanceTypeName(config.getGuestFullName());
                    ui.setAvailabilityZone(config.getVmPathName());
                }
            }
            VirtualMachineRuntimeInfo runtime = vm.getRuntime();
            if (runtime != null) {
                ManagedObjectReference host = runtime.getHost();
                if (host != null) {
                    HostSystem h = new HostSystem(si.getServerConnection(), host);
                    ui.setHost(h.getName());
                }
            }
            ui.setCloudCode(VcenterConstant.CLOUD_CODE);
            listRet.add(ui);
        }
    }
    return listRet;
}


private class VmCreateRunnable2 implements Runnable {
    private VcCreateInstanceReq req;
    private Task task;
    private ServiceInstance si;

    public VmCreateRunnable2(Task task, VcCreateInstanceReq req, ServiceInstance si) {
        this.req = req;
        this.task = task;
        this.si = si;
    }

    @Override
    public void run() {
        try {
            if (!StringUtils.equals(Task.SUCCESS, this.task.waitForTask())) {
                new Exception("dictionary.operation_failed");
            }
            /* 获取虚拟机 */
            String vcenterName = req.getDataCenterName();
            String vmName = req.getVmName();
            Datacenter dataCenter = (Datacenter) new InventoryNavigator(si.getRootFolder()).searchManagedEntity("Datacenter", vcenterName);

            VirtualMachine vm = (VirtualMachine) new InventoryNavigator(dataCenter).searchManagedEntity("VirtualMachine", vmName);

            // 检查当前虚机是否有scsi控制器,如果没有则新增配置
            if (!getVirtualSCSIController(vm)) {
                createScsiController(vm);
            }

            VirtualMachineConfigOption configOption = vm.getEnvironmentBrowser().queryConfigOption(null, null);
            GuestOsDescriptor[] guestOsDescs = configOption.getGuestOSDescriptor();
            String ethernetCardClass = "VirtualPCNet32";
            for (GuestOsDescriptor guestOsDesc : guestOsDescs) {
                if (guestOsDesc.getId().equals(vm.getConfig().getGuestId())) {
                    ethernetCardClass = guestOsDesc.getRecommendedEthernetCard();
                }
            }
            String nicName = "";
            String updateName = req.getVmName();
            String updateMemValue = req.getMemory() + "";
            String updateCPUValue = req.getCPU() + "";

            VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
            // 更新名称
            vmConfigSpec.setName(updateName);
            // 更新内存
            if (!"".equals(updateMemValue)) {
                try {
                    vmConfigSpec.setMemoryMB(Long.parseLong(updateMemValue));
                } catch (java.lang.NumberFormatException nfe) {
                    log.error(errorName+"VmCreateRunnable2##run",nfe);
                }
            }
            // 更新CPU
            if (!"".equals(updateCPUValue)) {
                try {
                    vmConfigSpec.setNumCPUs(Integer.parseInt(updateCPUValue));
                } catch (java.lang.NumberFormatException nfe) {
                    log.error(errorName+"VmCreateRunnable2##run",nfe);
                }
            }
            List<VirtualDeviceConfigSpec> vdcsList = new ArrayList<>();

            if(req.getDiskArray() != null) {
             // 更新磁盘容量
                List<VcCreateInstanceReq.EditDiskParam> diskArray = req.getDiskArray();
                for (int i = 0; i < diskArray.size(); i++) {
                    VcCreateInstanceReq.EditDiskParam disk = diskArray.get(i);
                    VirtualDeviceConfigSpec vdiskSpec = updateDiskVirtualDeviceConfigSpec(vm, disk.getDeviceLabel(), disk.getDeviceValueKB());
                    if (vdiskSpec != null)
                        vdcsList.add(vdiskSpec);
                }    
            }
            
            if(req.getNewdiskArray() != null) {
                // 新增磁盘
                List<VcCreateInstanceReq.AddDiskParam> newdiskArray = req.getNewdiskArray();
                if (newdiskArray != null && newdiskArray.size() > 0) {
                    for (int i = 0; i < newdiskArray.size(); i++) {
                        VcCreateInstanceReq.AddDiskParam dskmp = newdiskArray.get(i);
                        VirtualMachineDeviceManager vmdm = new VirtualMachineDeviceManager(vm);
                        vmdm.createHardDisk(dskmp.getMemValue(), VirtualDiskType.preallocated, VirtualDiskMode.persistent);
                    }
                }
            }

            // 删除网卡
            List<VirtualDeviceConfigSpec> removeAll = removeNICDeviceConfigSpecForAll(dataCenter, vm);
            if (removeAll.size() > 0) {
                vdcsList.addAll(removeAll);
            }
            // 新增网卡
            if (StringUtils.isNotBlank(req.getNet())) {
                VirtualDeviceConfigSpec nicSpec = createNicSpec(si, req.getNet(), nicName, ethernetCardClass, dataCenter, null);
                vdcsList.add(nicSpec);
            }

            if (vdcsList.size() > 0) {
                VirtualDeviceConfigSpec[] vdiskSpecArray = new VirtualDeviceConfigSpec[vdcsList.size()];
                for (int i = 0; i < vdiskSpecArray.length; i++) {
                    vdiskSpecArray[i] = vdcsList.get(i);
                }
                vmConfigSpec.setDeviceChange(vdiskSpecArray);
            }

            // 配置vnc相关参数
            OptionValue ov1 = new OptionValue();
            ov1.setKey("RemoteDisplay.vnc.enabled");
            ov1.setValue("TRUE");
            OptionValue ov2 = new OptionValue();

            try {
                int port = getRemoteDisplayVncPort(vm);
                ov2.setKey("RemoteDisplay.vnc.port");
                ov2.setValue(port);
            } catch (Exception e) {
                log.error(errorName+"VmCreateRunnable2##run",e);
            }
            OptionValue ov3 = new OptionValue();
            ov3.setKey("RemoteDisplay.vnc.keyMap");
            ov3.setValue("en-us");
            addVmOptionValue(vmConfigSpec, ov1, ov2, ov3);
            Task task = vm.reconfigVM_Task(vmConfigSpec);
            if (!Task.SUCCESS.equals(task.waitForTask())) {
                new Exception("dictionary.operation_failed");
            } else {
                vm.refreshStorageInfo();
            }
        } catch (Exception e) {
            log.error(errorName+"instance error",e);
        } finally {
            if (si != null) {
                vcenterClient.closeConnection(si);
            }
        }
    }
}


public static void addVmOptionValue(VirtualMachineConfigSpec vmConfigSpec, OptionValue... op) {
    OptionValue[] optionValues = vmConfigSpec.getExtraConfig();
    int ovAdd = op.length;
    int ovLength = optionValues != null ? optionValues.length + ovAdd : ovAdd;
    OptionValue[] optionValuesNew = new OptionValue[ovLength];
    int i = 0;
    if (ovLength > ovAdd) {
        for (; i < optionValues.length; i++) {
            optionValuesNew[i] = optionValues[i];
        }
    }
    for (int j = 0; j < ovAdd; j++) {
        optionValuesNew[i++] = op[j];
    }
    vmConfigSpec.setExtraConfig(optionValuesNew);
}

private Datastore getDatastoreByName(Datacenter dc, String name) {
    Datastore[] dts = dc.getDatastores();
    for (int i = 0; i < dts.length; i++) {
        Datastore dt = dts[i];
        if (name.equals(dt.getInfo().getName())) {
            return dt;
        }
    }
    return null;
}

/**
 * 添加所有假实例id到redis
 */
private void send2Redis(List<String> resources){
    try {
        if(null!=resources && !resources.isEmpty()){
            redisTemplate.opsForList().leftPushAll(EcsStatusEnums.VM_CREATING.getKey(), resources);
        }
    }catch (Exception e){
        log.error(errorName+"send2Redis" ,e);
    }
}


@Override
public boolean createVirtualMachine(ServiceInstance si, VcCreateInstanceReq req)
{
    log.info(errorName + "createVirtualMachine##VcCreateInstanceReq={}", JSONUtil.toJsonStr(req));
    try
    {
        Folder rootFolder = si.getRootFolder();//跟目录
        ManagedEntity dc = new InventoryNavigator(rootFolder).searchManagedEntity(ManagedEntityType.Datacenter,
                req.getDataCenterName());
        InventoryNavigator inventoryNavigator = new InventoryNavigator(dc);//文件夹目录
        Datacenter datacenter = (Datacenter) dc;
        Folder newFolder = (Folder) inventoryNavigator.searchManagedEntity(ManagedEntityType.Folder, req.getFolderName());;
        if(newFolder == null){
            newFolder = datacenter.getVmFolder().createFolder(req.getFolderName());
        }

        String clusterName = req.getCluster();
        String name = req.getVmName();
        String hostName = req.getHost();
        String dataStore = req.getDataStore();
        
        HostSystem host = (HostSystem) inventoryNavigator.searchManagedEntity(ManagedEntityType.HostSystem, hostName);
        
        ClusterComputeResource cluster = (ClusterComputeResource) inventoryNavigator.searchManagedEntity(ManagedEntityType.ClusterComputeResource, clusterName);
        
        
        VirtualMachineConfigSpec vmConfigSpec = createVmConfigSpec(name, dataStore, req.getNet(), req.getDiskArray(), cluster, host);
        
        vmConfigSpec.setName(name);
        vmConfigSpec.setAnnotation("VirtualMachine Annotation");
        vmConfigSpec.setMemoryMB(DataType.getAsLong(req.getMemory()));
        vmConfigSpec.setNumCPUs(req.getCPU());
        vmConfigSpec.setGuestId(req.getGuestOsId());
        
        Task task = newFolder.createVM_Task(vmConfigSpec, cluster.getResourcePool(), host);
        String result = task.waitForTask();
        if(Task.SUCCESS.equals(result)){
            //设置开机
            VirtualMachine virtualMachine = (VirtualMachine) inventoryNavigator.searchManagedEntity(ManagedEntityType.VirtualMachine, name);
            virtualMachine.powerOnVM_Task(null);
            return true;
        }else{
            return false;
        }
    }
    catch (Exception e) {
        log.error(errorName+"createVirtualMachine", e);
    }

    return false;
}

private ConfigTarget getConfigTargetForHost(ClusterComputeResource cluster, HostSystem host) throws RuntimeFault, RemoteException
{
    EnvironmentBrowser envBrowseMor  = cluster.getEnvironmentBrowser();
    ConfigTarget configTarget = envBrowseMor.queryConfigTarget(host);
    if (configTarget == null)
    {
        throw new RuntimeException("InstanceServiceImpl###getConfigTargetForHost####No ConfigTarget found in ComputeResource: " + host.getName());
    }
    return configTarget;
}

private VirtualMachineConfigSpec createVmConfigSpec(String vmName, String datastoreName, String networkName, List<EditDiskParam> diskArray, ClusterComputeResource cluster, HostSystem host) throws RuntimeFault, RemoteException{

           ConfigTarget configTarget = getConfigTargetForHost(cluster, host);
           List<VirtualDevice> defaultDevices = getDefaultDevices(cluster, host);
           VirtualMachineConfigSpec configSpec = new VirtualMachineConfigSpec();
           ManagedObjectReference datastoreRef = null;
           if (datastoreName != null) {
               boolean flag = false;
               for (int i = 0; i < configTarget.getDatastore().length; i++) {
                   VirtualMachineDatastoreInfo vdsInfo = configTarget.getDatastore()[i];
                   DatastoreSummary dsSummary = vdsInfo.getDatastore();
                   if (dsSummary.getName().equals(datastoreName)) {
                       flag = true;
                       if (dsSummary.isAccessible()) {
                           datastoreRef = dsSummary.getDatastore();
                       } else {
                           throw new RuntimeException("InstanceServiceImpl###getConfigTargetForHost####Specified Datastore is not accessible");
                       }
                       break;
                   }
               }
               if (!flag) {
                   throw new RuntimeException("InstanceServiceImpl###getConfigTargetForHost####Specified Datastore is not Found");
               }
           } else {
               throw new RuntimeException("InstanceServiceImpl###getConfigTargetForHost####No Datastore found on host");
           }
           
           String datastoreVolume = getVolumeName(datastoreName);
           VirtualMachineFileInfo vmfi = new VirtualMachineFileInfo();
           vmfi.setVmPathName(datastoreVolume);
           configSpec.setFiles(vmfi);
          
           // 添加 scsi 控制器
           int diskCtlrKey = 1;
           VirtualDeviceConfigSpec scsiCtrlSpec = new VirtualDeviceConfigSpec();
           scsiCtrlSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
           VirtualLsiLogicController scsiCtrl = new VirtualLsiLogicController();
           scsiCtrl.setBusNumber(0);
           scsiCtrlSpec.setDevice(scsiCtrl);
           scsiCtrl.setKey(diskCtlrKey);
           scsiCtrl.setSharedBus(VirtualSCSISharing.noSharing);
           String ctlrType = scsiCtrl.getClass().getName();
           ctlrType = ctlrType.substring(ctlrType.lastIndexOf(".") + 1);
           
           // 查找IDE控制器
           VirtualDevice ideCtlr = null;
           for (int di = 0; di < defaultDevices.size(); di++) {
               if (defaultDevices.get(di) instanceof VirtualIDEController) {
                   ideCtlr = defaultDevices.get(di);
                   break;
               }
           }

           // 添加软盘
           VirtualDeviceConfigSpec floppySpec = new VirtualDeviceConfigSpec();
           floppySpec.setOperation(VirtualDeviceConfigSpecOperation.add);
           VirtualFloppy floppy = new VirtualFloppy();
           VirtualFloppyDeviceBackingInfo flpBacking =
                   new VirtualFloppyDeviceBackingInfo();
           flpBacking.setDeviceName("/dev/fd0");
           floppy.setBacking(flpBacking);
           floppy.setKey(3);
           floppySpec.setDevice(floppy);

           // 添加物理设备---》光盘
           VirtualDeviceConfigSpec cdSpec = null;
           if (ideCtlr != null) {
               cdSpec = new VirtualDeviceConfigSpec();
               cdSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
               VirtualCdrom cdrom = new VirtualCdrom();
               VirtualCdromIsoBackingInfo cdDeviceBacking = new VirtualCdromIsoBackingInfo();
               cdDeviceBacking.setDatastore(datastoreRef);
               String fileName = datastoreVolume + UUID.randomUUID().toString().substring(0,8) + ".iso";
               cdDeviceBacking.setFileName(fileName);
               cdrom.setBacking(cdDeviceBacking);
               cdrom.setKey(20);
               cdrom.setControllerKey(new Integer(ideCtlr.getKey()));
               cdrom.setUnitNumber(new Integer(0));
               cdSpec.setDevice(cdrom);
           }

           Long diskSizeKb = diskArray.get(0).getDeviceValueKB();
           // 创建虚拟机磁盘
           VirtualDeviceConfigSpec diskSpec =  createVirtualDisk(datastoreName, diskCtlrKey, datastoreRef, diskSizeKb);

           // 添加网卡
           VirtualDeviceConfigSpec nicSpec = new VirtualDeviceConfigSpec();
           if (networkName != null) {
               nicSpec.setOperation(VirtualDeviceConfigSpecOperation.add);
               VirtualEthernetCard nic = new VirtualVmxnet3();   
               VirtualEthernetCardNetworkBackingInfo nicBacking = new VirtualEthernetCardNetworkBackingInfo();
               nicBacking.setDeviceName(networkName);
               nic.setAddressType("Generated"); //自动生成mac地址
               nic.setBacking(nicBacking);
               nic.setKey(4);
               nicSpec.setDevice(nic);
           }

           List<VirtualDeviceConfigSpec> deviceConfigSpec = new ArrayList<VirtualDeviceConfigSpec>();
           deviceConfigSpec.add(scsiCtrlSpec);
           deviceConfigSpec.add(floppySpec);
           deviceConfigSpec.add(diskSpec);
           if (ideCtlr != null) {
               deviceConfigSpec.add(cdSpec);
               deviceConfigSpec.add(nicSpec);
           } else {
               deviceConfigSpec = new ArrayList<VirtualDeviceConfigSpec>();
               deviceConfigSpec.add(nicSpec);
           }
           
           VirtualDeviceConfigSpec[] deviceChange = deviceConfigSpec.toArray(new VirtualDeviceConfigSpec[deviceConfigSpec.size()]);
           configSpec.setDeviceChange(deviceChange);
           return configSpec;
       }

private List<VirtualDevice> getDefaultDevices( ClusterComputeResource cluster, HostSystem host) throws RuntimeFault, RemoteException
{
    
    EnvironmentBrowser envBrowseMor  = cluster.getEnvironmentBrowser();
    VirtualMachineConfigOption cfgOpt = envBrowseMor.queryConfigOption(null, host);
    List<VirtualDevice> defaultDevs = null;
    if (cfgOpt == null)
    {
        throw new RuntimeException("InstanceServiceImpl###getDefaultDevices####No VirtualHardwareInfo found in ComputeResource: " + host.getName());
    }
    else
    {
        VirtualDevice[] lvds = cfgOpt.getDefaultDevice();
        if (lvds == null)
        {
            throw new RuntimeException("InstanceServiceImpl###getDefaultDevices####No Datastore found in ComputeResource");
        }
        else
        {
            defaultDevs = new ArrayList<VirtualDevice>();
            Collections.addAll(defaultDevs, lvds);
        }
    }
    return defaultDevs;
}

private VirtualDeviceConfigSpec createVirtualDisk(String volName, int diskCtlrKey,  ManagedObjectReference datastoreRef, long diskSizeKB)
{
    String volumeName = getVolumeName(volName);
    VirtualDeviceConfigSpec diskSpec = new VirtualDeviceConfigSpec();

    diskSpec.setFileOperation(VirtualDeviceConfigSpecFileOperation.create);
    diskSpec.setOperation(VirtualDeviceConfigSpecOperation.add);

    VirtualDisk disk = new VirtualDisk();
    VirtualDiskFlatVer2BackingInfo diskfileBacking = new VirtualDiskFlatVer2BackingInfo();

    diskfileBacking.setFileName(volumeName);
    diskfileBacking.setDiskMode("persistent");

    disk.setKey(new Integer(0));
    disk.setControllerKey(new Integer(diskCtlrKey));
    disk.setUnitNumber(new Integer(0));
    disk.setBacking(diskfileBacking);
    disk.setCapacityInKB(diskSizeKB);

    diskSpec.setDevice(disk);

    return diskSpec;
}

private String getVolumeName(String volName) {
    String volumeName = null;
    if (volName != null && volName.length() > 0) {
        volumeName = "[" + volName + "]";
    } else {
        volumeName = "[Local]";
    }

    return volumeName;
}

}

发布了5 篇原创文章 · 获赞 0 · 访问量 15

猜你喜欢

转载自blog.csdn.net/pingzhilidexingfu/article/details/105139707