cloudTower申请虚拟机流程
parent
3116e622ef
commit
4b6bf6bb54
|
@ -126,6 +126,15 @@ public class Cluster extends GenericEntity {
|
|||
private String memUsage;
|
||||
// fc 纳管
|
||||
|
||||
@IgnoreAll
|
||||
private Long cpuRemainder;
|
||||
@IgnoreAll
|
||||
private Long memoryRemainder;
|
||||
@IgnoreAll
|
||||
private Long diskRemainder;
|
||||
@IgnoreAll
|
||||
private List<Server> servers;
|
||||
|
||||
/**
|
||||
* @param creatorId
|
||||
* @param ownerId
|
||||
|
|
|
@ -164,6 +164,16 @@ public class DataStore extends GenericEntity {
|
|||
@IgnoreAll
|
||||
private String version;
|
||||
|
||||
@IgnoreAll
|
||||
private Long SpaceRemain;
|
||||
|
||||
public Long getSpaceRemain() {
|
||||
return SpaceRemain;
|
||||
}
|
||||
|
||||
public void setSpaceRemain(Long spaceRemain) {
|
||||
SpaceRemain = spaceRemain;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the vdcId
|
||||
|
|
|
@ -300,6 +300,10 @@ public class Server extends GenericEntity {
|
|||
private String cpuTotalMhz;
|
||||
|
||||
|
||||
@IgnoreAll
|
||||
private CloudVendor vendor;
|
||||
|
||||
|
||||
|
||||
public void preSave(Long creatorId, Long menderId, Long vendorId, Long vdcId, Long clusterId) {
|
||||
this.setCreatorId(creatorId);
|
||||
|
|
|
@ -81,6 +81,15 @@ public class Vdc extends GenericEntity {
|
|||
private String mgntNetworkType;//管理面ip版本,取值ipv4,ipv6
|
||||
//fc新增字段
|
||||
|
||||
|
||||
@IgnoreAll
|
||||
private Long cpuRemainder;
|
||||
@IgnoreAll
|
||||
private Long memoryRemainder;
|
||||
@IgnoreAll
|
||||
private Long diskRemainder;
|
||||
@IgnoreAll
|
||||
private List<Server> servers;
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.bocloud.database.core.intf.impl.BasicGenericDao;
|
|||
import com.bocloud.database.utils.QueryBuilder;
|
||||
import com.bocloud.ims.entity.resource.Network;
|
||||
import com.bocloud.ims.entity.resource.Server;
|
||||
import com.bocloud.orm.OrmGenericDaoImpl;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
|
@ -30,7 +31,7 @@ import java.util.Map;
|
|||
*
|
||||
*/
|
||||
@Repository("networkRepository")
|
||||
public class NetworkRepository extends BasicGenericDao<Network, Long> {
|
||||
public class NetworkRepository extends OrmGenericDaoImpl<Network, Long> {
|
||||
|
||||
public NetworkRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
|
||||
super(jdbcTemplate, npJdbcTemplate);
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.bocloud.common.utils.ListTool;
|
|||
import com.bocloud.common.utils.MapTools;
|
||||
import com.bocloud.database.core.intf.impl.BasicGenericDao;
|
||||
import com.bocloud.ims.entity.resource.ServerConfig;
|
||||
import com.bocloud.orm.OrmGenericDaoImpl;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
@ -20,7 +21,7 @@ import java.util.Map;
|
|||
*
|
||||
*/
|
||||
@Repository("serverConfigRepository")
|
||||
public class ServerConfigRepository extends BasicGenericDao<ServerConfig, Long> {
|
||||
public class ServerConfigRepository extends OrmGenericDaoImpl<ServerConfig, Long> {
|
||||
|
||||
public ServerConfigRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
|
||||
super(jdbcTemplate, npJdbcTemplate);
|
||||
|
|
|
@ -0,0 +1,471 @@
|
|||
package com.bocloud.ims.service.builder;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.cmp.driver.compute.ServerDriver;
|
||||
import com.bocloud.cmp.driver.compute.ServerTemplateDriver;
|
||||
import com.bocloud.cmp.driver.storage.VolumeDriver;
|
||||
import com.bocloud.cmp.model.NetworkCardModel;
|
||||
import com.bocloud.cmp.model.ServerModel;
|
||||
import com.bocloud.cmp.model.VolumeModel;
|
||||
import com.bocloud.cmp.vm.model.VmGenericParam;
|
||||
import com.bocloud.common.model.BocloudResult;
|
||||
import com.bocloud.common.model.RequestContext;
|
||||
import com.bocloud.ims.entity.resource.*;
|
||||
import com.bocloud.ims.repository.resource.*;
|
||||
import com.bocloud.ims.service.transporter.vendor.CloudTowerTransporter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* cloudTower
|
||||
*/
|
||||
public class CloudTowerServerBuilder implements ServerBuilder {
|
||||
private static final Logger logger = LoggerFactory.getLogger(CloudTowerServerBuilder.class);
|
||||
|
||||
private final CloudVendorRepository cloudVendorRepository;
|
||||
private final ServerRepository serverRepository;
|
||||
private final CloudServerRepository cloudServerRepository;
|
||||
private final ClusterRepository clusterRepository;
|
||||
private final VolumeRepository volumeRepository;
|
||||
private final VolumeTemplateRepository volumeTemplateRepository;
|
||||
private final ImageRepository imageRepository;
|
||||
private final SwitcherRepository switcherRepository;
|
||||
private final NetworkRepository networkRepository;
|
||||
private final NetworkCardRepository networkCardRepository;
|
||||
private final SubnetRepository subnetRepository;
|
||||
private final ServerVolumeRepository serverVolumeRepository;
|
||||
private final ServerImageRepository serverImageRepository;
|
||||
private final ServerDriver serverDriver;
|
||||
private final VolumeDriver volumeDriver;
|
||||
private final ServerTemplateDriver serverTemplateDriver;
|
||||
private final CloudTowerTransporter cloudTowerTransporter;
|
||||
private final RequestContext context;
|
||||
|
||||
private CloudVendor vendor;
|
||||
private VmGenericParam vmGenericParam;
|
||||
private ServerModel serverModel;
|
||||
|
||||
public CloudTowerServerBuilder(CloudVendorRepository cloudVendorRepository, ServerRepository serverRepository,
|
||||
CloudServerRepository cloudServerRepository, VolumeRepository volumeRepository,
|
||||
VolumeTemplateRepository volumeTemplateRepository, ImageRepository imageRepository,
|
||||
SwitcherRepository switcherRepository, NetworkRepository networkRepository,
|
||||
SubnetRepository subnetRepository, ServerVolumeRepository serverVolumeRepository,
|
||||
ServerImageRepository serverImageRepository, ServerDriver serverDriver,
|
||||
VolumeDriver volumeDriver, ServerTemplateDriver serverTemplateDriver,
|
||||
CloudTowerTransporter cloudTowerTransporter, RequestContext context,
|
||||
ClusterRepository clusterRepository, NetworkCardRepository networkCardRepository) {
|
||||
this.cloudVendorRepository = cloudVendorRepository;
|
||||
this.serverRepository = serverRepository;
|
||||
this.cloudServerRepository = cloudServerRepository;
|
||||
this.volumeRepository = volumeRepository;
|
||||
this.volumeTemplateRepository = volumeTemplateRepository;
|
||||
this.imageRepository = imageRepository;
|
||||
this.switcherRepository = switcherRepository;
|
||||
this.networkRepository = networkRepository;
|
||||
this.subnetRepository = subnetRepository;
|
||||
this.serverVolumeRepository = serverVolumeRepository;
|
||||
this.serverImageRepository = serverImageRepository;
|
||||
this.serverDriver = serverDriver;
|
||||
this.volumeDriver = volumeDriver;
|
||||
this.serverTemplateDriver = serverTemplateDriver;
|
||||
this.cloudTowerTransporter = cloudTowerTransporter;
|
||||
this.context = context;
|
||||
this.clusterRepository = clusterRepository;
|
||||
this.networkCardRepository = networkCardRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BocloudResult<ServerModel> prepare(JSONObject object) throws Exception {
|
||||
try {
|
||||
VmGenericParam vmGenericParam = object.toJavaObject(VmGenericParam.class);
|
||||
Long sourceServerId = null;
|
||||
ServerModel serverModel = new ServerModel();
|
||||
Cluster cluster = null;
|
||||
if (vmGenericParam.getTemplateId() != null) {
|
||||
// 从模板创建云主机
|
||||
sourceServerId = vmGenericParam.getTemplateId();
|
||||
|
||||
CloudServer template = cloudServerRepository.query(vmGenericParam.getTemplateId());
|
||||
Assert.notNull(template, "id为" + vmGenericParam.getTemplateId() + "云主机模板不存在");
|
||||
vmGenericParam.setVendorId(template.getVendorId());
|
||||
serverModel.setInstanceId(template.getInstanceId());
|
||||
cluster = clusterRepository.query(vmGenericParam.getClusterId());
|
||||
Assert.notNull(cluster, "id为" + vmGenericParam.getClusterId() + "集群不存在");
|
||||
serverModel.setClusterUuid(cluster.getUuid());
|
||||
if (vmGenericParam.getFullClone() == null) {
|
||||
vmGenericParam.setFullClone(true);
|
||||
}
|
||||
if (vmGenericParam.getFullClone() && vmGenericParam.getServerId() == 0) {
|
||||
return new BocloudResult<>(false, "完全拷贝克隆需要明确指定目标云主机所属主机");
|
||||
}
|
||||
serverModel.setFullClone(vmGenericParam.getFullClone());
|
||||
|
||||
serverModel.setVmHostName(vmGenericParam.getVmHostName());
|
||||
serverModel.setPassword(vmGenericParam.getPassword());
|
||||
}
|
||||
|
||||
vendor = cloudVendorRepository.query(vmGenericParam.getVendorId());
|
||||
Assert.notNull(vendor, "ID为" + vmGenericParam.getVendorId() + "云平台不存在");
|
||||
|
||||
Assert.notNull(vmGenericParam.getName(), "需要为云主机指定名称");
|
||||
CloudServer vmbyName = cloudServerRepository.getByName(vmGenericParam.getName(), vendor.getId());
|
||||
Assert.isNull(vmbyName, "名为" + vmGenericParam.getName() + "的云主机已经存在,请重新命名");
|
||||
serverModel.setName(vmGenericParam.getName());
|
||||
|
||||
if (vmGenericParam.getHa() == null) {
|
||||
vmGenericParam.setHa(true);
|
||||
}
|
||||
serverModel.setHa(vmGenericParam.getHa());
|
||||
|
||||
Assert.notNull(vmGenericParam.getServerId(), "需要为云主机指定所属主机");
|
||||
if (vmGenericParam.getServerId() == 0) {
|
||||
serverModel.setAutoSchedule(true);
|
||||
} else {
|
||||
Server host = serverRepository.query(vmGenericParam.getServerId());
|
||||
Assert.notNull(host, "id为" + vmGenericParam.getServerId() + "主机不存在");
|
||||
serverModel.setHostIp(host.getVmotionIp());
|
||||
serverModel.setHostUuid(host.getUuid());
|
||||
}
|
||||
|
||||
Assert.notNull(vmGenericParam.getCpu(), "需要为云主机指定CPU配置");
|
||||
serverModel.setCpu(vmGenericParam.getCpu());
|
||||
|
||||
Assert.notNull(vmGenericParam.getMemory(), "需要为云主机指定内存配置");
|
||||
serverModel.setMemory(vmGenericParam.getMemory());
|
||||
|
||||
Assert.notNull(vmGenericParam.getFirmware(), "需要为云主机指定引导选项");
|
||||
serverModel.setFirmware(vmGenericParam.getFirmware());
|
||||
|
||||
Assert.notNull(vmGenericParam.getStatus(), "参数status不能为空");
|
||||
serverModel.setStatus(vmGenericParam.getStatus());
|
||||
|
||||
if (StringUtils.isNotEmpty(vmGenericParam.getRemark())) {
|
||||
serverModel.setRemark(vmGenericParam.getRemark());
|
||||
}
|
||||
|
||||
Assert.notEmpty(vmGenericParam.getDiskDevices(), "需要为云主机定义虚拟盘");
|
||||
List<VolumeModel> disks = new ArrayList<>();
|
||||
for (int i = 0; i < vmGenericParam.getDiskDevices().size(); i++) {
|
||||
VolumeModel diskDevice = vmGenericParam.getDiskDevices().get(i);
|
||||
VolumeModel disk = new VolumeModel();
|
||||
disk.setType(diskDevice.getType());
|
||||
|
||||
if ("reserveDisk".equals(diskDevice.getType())) {
|
||||
Assert.notNull(diskDevice.getId(), "需要指定要保留的虚拟卷");
|
||||
Volume volume = volumeRepository.query(diskDevice.getId());
|
||||
Assert.notNull(volume, "id为" + diskDevice.getId() + "的虚拟卷不存在");
|
||||
|
||||
ServerVolume serverVolume = serverVolumeRepository
|
||||
.getByServerIdAndVolumeId(sourceServerId, volume.getId());
|
||||
Assert.notNull(serverVolume, "id为" + diskDevice.getId() + "的虚拟卷并未挂载当前云主机");
|
||||
|
||||
disk.setPath(volume.getPath());
|
||||
disk.setTemplateUuid(serverVolume.getTemplateUuid());
|
||||
|
||||
if (StringUtils.isNotEmpty(diskDevice.getName())) {
|
||||
disk.setName(diskDevice.getName());
|
||||
} else {
|
||||
disk.setName(volume.getName());
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(diskDevice.getBus())) {
|
||||
disk.setBus(diskDevice.getBus());
|
||||
} else {
|
||||
disk.setBus(serverVolume.getBus());
|
||||
}
|
||||
} else if ("removeDisk".equals(diskDevice.getType())) {
|
||||
Assert.notNull(diskDevice.getId(), "需要指定要删除的虚拟卷");
|
||||
Volume volume = volumeRepository.query(diskDevice.getId());
|
||||
Assert.notNull(volume, "id为" + diskDevice.getId() + "的虚拟卷不存在");
|
||||
|
||||
ServerVolume serverVolume = serverVolumeRepository
|
||||
.getByServerIdAndVolumeId(sourceServerId, volume.getId());
|
||||
Assert.notNull(serverVolume, "id为" + diskDevice.getId() + "的虚拟卷并未挂载当前云主机");
|
||||
|
||||
disk.setPath(volume.getPath());
|
||||
} else if ("reserveISO".equals(diskDevice.getType())) {
|
||||
Assert.notNull(diskDevice.getDiffKey(), "需要指定要保留的ISO映像的KEY");
|
||||
List<ServerImage> serverImages = serverImageRepository.listByServerId(sourceServerId);
|
||||
ServerImage serverImage = serverImages.stream()
|
||||
.filter(si -> diskDevice.getDiffKey().equals(si.getDiffKey())).findFirst().orElse(null);
|
||||
Assert.notNull(serverImage, "KEY为" + diskDevice.getDiffKey() + "的ISO映像不存在");
|
||||
disk.setKey(serverImage.getDiffKey());
|
||||
disk.setBus(serverImage.getBus());
|
||||
|
||||
if (diskDevice.getId() != null) {
|
||||
Image image = imageRepository.query(diskDevice.getId());
|
||||
Assert.notNull(image, "id为" + diskDevice.getId() + "的ISO映像不存在");
|
||||
disk.setPath(image.getFilePath());
|
||||
}
|
||||
|
||||
if (diskDevice.getDisabled() != null) {
|
||||
disk.setDisabled(diskDevice.getDisabled());
|
||||
} else {
|
||||
disk.setDisabled(serverImage.getDisabled());
|
||||
}
|
||||
} else if ("removeISO".equals(diskDevice.getType())) {
|
||||
Assert.notNull(diskDevice.getDiffKey(), "需要指定要删除的ISO映像的KEY");
|
||||
List<ServerImage> serverImages = serverImageRepository.listByServerId(sourceServerId);
|
||||
ServerImage serverImage = serverImages.stream()
|
||||
.filter(si -> diskDevice.getDiffKey().equals(si.getDiffKey())).findFirst().orElse(null);
|
||||
Assert.notNull(serverImage, "KEY为" + diskDevice.getDiffKey() + "的ISO映像不存在");
|
||||
disk.setKey(serverImage.getDiffKey());
|
||||
|
||||
Image image = imageRepository.query(serverImage.getImageId());
|
||||
Assert.notNull(image, "id为" + diskDevice.getId() + "的ISO映像不存在");
|
||||
if ("HIDE".equals(image.getCatalog())) {
|
||||
disk.setPath("");
|
||||
} else {
|
||||
disk.setPath(image.getFilePath());
|
||||
}
|
||||
} else if ("newDisk".equals(diskDevice.getType())) {
|
||||
diskDevice.setName(vmGenericParam.getName() + "_disk" + i);
|
||||
Assert.notNull(diskDevice.getName(), "需要为新建的虚拟卷指定名称");
|
||||
Volume volumeByName = volumeRepository.getByName(vendor.getId(), diskDevice.getName());
|
||||
Assert.isNull(volumeByName, "名为" + diskDevice.getName() + "的虚拟卷已经存在,请重新命名");
|
||||
disk.setName(diskDevice.getName());
|
||||
disk.setSize(diskDevice.getSize());
|
||||
if (disk.getSize() == null){
|
||||
disk.setSize(diskDevice.getDisk());
|
||||
}
|
||||
Assert.notNull(disk.getSize(), "需要为新建的虚拟卷指定容量");
|
||||
disk.setBlockSize(1D);
|
||||
disk.setBlockCount(disk.getSize() * 1024L * 1024L * 1024L);
|
||||
|
||||
Assert.notNull(diskDevice.getBus(), "需要为新建的虚拟卷指定总线");
|
||||
disk.setBus(diskDevice.getBus());
|
||||
|
||||
Assert.notNull(diskDevice.getVolumeTemplateId(), "需要为新建的虚拟卷指定存储策略");
|
||||
VolumeTemplate volumeTemplate = volumeTemplateRepository.get(diskDevice.getVolumeTemplateId());
|
||||
Assert.notNull(volumeTemplate, "id为" + diskDevice.getVolumeTemplateId() + "的存储策略不存在");
|
||||
disk.setVolumeTemplateUuid(volumeTemplate.getUuid());
|
||||
} else if ("mountDisk".equals(diskDevice.getType())) {
|
||||
Assert.notNull(diskDevice.getId(), "需要指定要挂载的虚拟卷");
|
||||
Volume volume = volumeRepository.query(diskDevice.getId());
|
||||
Assert.notNull(volume, "id为" + diskDevice.getId() + "的虚拟卷不存在");
|
||||
disk.setPath(volume.getPath());
|
||||
|
||||
Assert.notNull(diskDevice.getBus(), "需要为新建的虚拟卷指定总线");
|
||||
disk.setBus(diskDevice.getBus());
|
||||
} else if ("mountISO".equals(diskDevice.getType())) {
|
||||
disk.setBus("ide");
|
||||
|
||||
Assert.notNull(diskDevice.getId(), "需要指定要挂载的ISO映像");
|
||||
Image image = imageRepository.query(diskDevice.getId());
|
||||
Assert.notNull(image, "id为" + diskDevice.getId() + "的ISO映像不存在");
|
||||
disk.setPath(image.getFilePath());
|
||||
|
||||
Assert.notNull(diskDevice.getDisabled(), "需要参数diskDevices.disabled");
|
||||
disk.setDisabled(diskDevice.getDisabled());
|
||||
} else {
|
||||
return new BocloudResult<>(false, "未知的虚拟盘类型");
|
||||
}
|
||||
disks.add(disk);
|
||||
}
|
||||
serverModel.setDiskDevices(disks);
|
||||
|
||||
/**
|
||||
* 调整工单网卡参数
|
||||
*/
|
||||
// 根据集群查询网卡信息
|
||||
Network network1 = null;
|
||||
if (cluster != null) {
|
||||
network1 = networkRepository.queryProxy()
|
||||
.col(Network::getClusterUuid).eq(cluster.getUuid())
|
||||
.col(Network::getType).eq("VM")
|
||||
.col(Network::getDeleted).eq(false)
|
||||
.list().get(0);
|
||||
}
|
||||
Assert.notEmpty(vmGenericParam.getNetworkCards(), "需要为云主机定义虚拟网卡");
|
||||
for (NetworkCardModel netcard : vmGenericParam.getNetworkCards()) {
|
||||
Assert.notNull(netcard.getNetworkId(), "需要为虚拟网卡指定网络");
|
||||
Network network = networkRepository.query(netcard.getNetworkId());
|
||||
Assert.notNull(network, "未找到id为" + netcard.getNetworkId() + "的虚拟网络");
|
||||
if (network1 != null) {
|
||||
logger.info("当前虚拟网络为:{}", JSONObject.toJSONString(network1));
|
||||
netcard.setNetworkUuid(network1.getNetworkUuid());
|
||||
} else {
|
||||
netcard.setNetworkUuid(network.getNetworkUuid());
|
||||
}
|
||||
}
|
||||
serverModel.setNetworkCards(vmGenericParam.getNetworkCards());
|
||||
|
||||
this.serverModel = serverModel;
|
||||
this.vmGenericParam = vmGenericParam;
|
||||
|
||||
object.remove("id");
|
||||
|
||||
return new BocloudResult<>(true, serverModel, "success");
|
||||
} catch (Exception e) {
|
||||
logger.error("Prepare Cloud-Tower云主机失败:{}", e.getMessage(), e);
|
||||
return new BocloudResult<>(false, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BocloudResult<CloudServer> builder(CloudServer server) throws Exception {
|
||||
try {
|
||||
String vlan = "";
|
||||
try {
|
||||
List<NetworkCardModel> networkCards = server.getNetworkCards();
|
||||
for (NetworkCardModel networkCard : networkCards) {
|
||||
vlan = networkRepository.query(networkCard.getNetworkId()).getName();
|
||||
break;
|
||||
}
|
||||
logger.info("获取vlan名称成功");
|
||||
} catch (Exception e) {
|
||||
logger.error("获取vlan名称失败", e);
|
||||
}
|
||||
// 执行创建
|
||||
BocloudResult createResult;
|
||||
if (vmGenericParam.getTemplateId() != null) {
|
||||
logger.info("serverModel:{}", JSON.toJSONString(serverModel));
|
||||
// 从模板创建云主机
|
||||
createResult = serverDriver
|
||||
.create(vendor.getUuid(), null, serverModel.getInstanceId(), serverModel);
|
||||
Assert.isTrue(createResult.isSuccess(), createResult.getMessage());
|
||||
} else if (vmGenericParam.getId() != null) {
|
||||
// 从云主机克隆云主机
|
||||
createResult = serverDriver.cloneAsVm(vendor.getUuid(), null, serverModel);
|
||||
Assert.isTrue(createResult.isSuccess(), createResult.getMessage());
|
||||
} else {
|
||||
// 创建空白云主机
|
||||
createResult = serverDriver.create(vendor.getUuid(), null, serverModel);
|
||||
Assert.isTrue(createResult.isSuccess(), createResult.getMessage());
|
||||
}
|
||||
// 获取云主机数据
|
||||
ServerModel serverModel = (ServerModel) createResult.getData();
|
||||
if (vmGenericParam.getTemplateId() != null) {
|
||||
// 从模板创建云主机
|
||||
}
|
||||
// 查询所属宿主机
|
||||
String serverIp = serverModel.getServerVal();
|
||||
Server host = serverRepository.queryBy3Ip(serverIp);
|
||||
Assert.notNull(host, "未找到IP为" + serverIp + "的主机");
|
||||
// 保存云主机数据
|
||||
cloudTowerTransporter.convert(serverModel, server);
|
||||
// 获取IP信息
|
||||
if(StringUtils.isBlank(serverModel.getManagerIp())) {
|
||||
logger.info("开始获取tower虚拟机IP地址......");
|
||||
while (true) {
|
||||
BocloudResult detail = serverDriver.detail(serverModel.getInstanceId(), vendor.getUuid(), null);
|
||||
if (detail.isSuccess()) {
|
||||
ServerModel model = (ServerModel) detail.getData();
|
||||
if (StringUtils.isBlank(model.getManagerIp())) {
|
||||
Thread.sleep(3000L);
|
||||
} else {
|
||||
logger.info("获取tower虚拟机IP地址成功{}......",model.getManagerIp());
|
||||
// 保存云主机数据
|
||||
cloudTowerTransporter.convert(model, server);
|
||||
List<NetworkCardModel> netcards = model.getNetcards();
|
||||
List<NetworkCard> networkCardList = new ArrayList<>();
|
||||
for (NetworkCardModel netcard : netcards) {
|
||||
NetworkCard networkCard = new NetworkCard();
|
||||
networkCard.setCategory("VM");
|
||||
networkCard.setHostId(server.getId());
|
||||
networkCard.setName(vlan);
|
||||
networkCard.setCreatorId(context.getTarget());
|
||||
networkCard.setSubnetUuid(netcard.getSubnetUuid());
|
||||
networkCard.setInstanceId(netcard.getInstanceId());
|
||||
networkCard.setVlan(netcard.getVlan());
|
||||
networkCard.setNetmask(netcard.getNetmask());
|
||||
networkCard.setIpAddress(netcard.getIpAddress());
|
||||
networkCard.setModel(netcard.getModel());
|
||||
networkCard.setUsed(netcard.getUsed());
|
||||
networkCard.setMac(netcard.getMac());
|
||||
networkCard.setNetworkcardUuid(netcard.getNetworkcardUuid());
|
||||
networkCard.setVendorId(vendor.getId());
|
||||
networkCard.setGmtCreate(new Date());
|
||||
networkCard.setDeleted(false);
|
||||
networkCardList.add(networkCard);
|
||||
}
|
||||
for (NetworkCard networkCard : networkCardList) {
|
||||
networkCardRepository.save(networkCard);
|
||||
}
|
||||
logger.info(server.getName() + ":创建虚拟机添加网卡成功");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
server.setHostId(host.getId());
|
||||
server.setVendorId(vendor.getId());
|
||||
server.setVendorType(vendor.getType());
|
||||
cloudServerRepository.update(server);
|
||||
// 保存新建的虚拟卷数据
|
||||
/* for (Map.Entry<String, Object> taskResourceEntry : taskResource.entrySet()) {
|
||||
String taskResourceUuid = taskResourceEntry.getKey();
|
||||
if (taskResourceUuid.equals(server.getInstanceId())) {
|
||||
continue;
|
||||
}
|
||||
BocloudResult volumeResult = volumeDriver.detail(taskResourceUuid, vendor.getUuid(), null);
|
||||
Assert.isTrue(volumeResult.isSuccess(), volumeResult.getMessage());
|
||||
VolumeModel volumeModel = (VolumeModel) volumeResult.getData();
|
||||
|
||||
if (volumeModel != null) {
|
||||
logger.info("查询名为[{}]cloudTower卷大小为:{}", volumeModel.getName(), volumeModel.getSize());
|
||||
Volume existsVolume = volumeRepository.getByVolumeUuid(volumeModel.getUuid());
|
||||
if (existsVolume == null) {
|
||||
String volumeTemplateUuid = volumeModel.getVolumeTemplateUuid();
|
||||
VolumeTemplate volumeTemplate = volumeTemplateRepository.getByUuid(volumeTemplateUuid);
|
||||
Assert.notNull(volumeTemplate, "未找到UUID为" + volumeTemplateUuid + "的存储策略");
|
||||
|
||||
Volume volume = new Volume();
|
||||
cloudTowerTransporter.convert(volumeModel, volume);
|
||||
volume.setVendorId(vendor.getId());
|
||||
volume.setTemplateId(volumeTemplate.getId());
|
||||
volume.setCreatorId(context.getTarget());
|
||||
volume.setGmtCreate(new Date());
|
||||
volume.setRegionId(server.getRegionId());
|
||||
volume.setRegion(server.getRegionId());
|
||||
volumeRepository.save(volume);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
// 保存云主机网卡数据
|
||||
// cloudTowerTransporter.syncNetworkCard(server, Optional.ofNullable(serverModel.getNetworkCards()).orElse(new ArrayList<>()), context.getTarget());
|
||||
// 保存云主机关联ISO镜像
|
||||
List<VolumeModel> imageModels = Optional.ofNullable(serverModel.getDiskDevices()).orElse(new ArrayList<>()).stream()
|
||||
.filter(d -> "cdrom".equalsIgnoreCase(d.getType())).collect(Collectors.toList());
|
||||
cloudTowerTransporter.syncServerImage(server, imageModels, context.getTarget());
|
||||
// 保存云主机关联虚拟盘
|
||||
List<VolumeModel> volumeModels = Optional.ofNullable(serverModel.getDiskDevices()).orElse(new ArrayList<>()).stream()
|
||||
.filter(d -> "disk".equalsIgnoreCase(d.getType())).collect(Collectors.toList());
|
||||
for (VolumeModel volumeModel : volumeModels) {
|
||||
String volumeUuid = volumeModel.getVolumeUuid();
|
||||
Volume volume = volumeRepository.getByVolumeUuid(volumeUuid);
|
||||
Optional<VolumeTemplate> dbVolumeTemplateOpt = Optional.of(volumeModel)
|
||||
.map(VolumeModel::getVolumeTemplateUuid).map(volumeTemplateRepository::getByName);
|
||||
if (volume == null) {
|
||||
volume = new Volume();
|
||||
cloudTowerTransporter.convert(volumeModel, volume);
|
||||
volume.setVendorId(vendor.getId());
|
||||
volume.setServerId(server.getId());
|
||||
volume.setVendorId(server.getVendorId());
|
||||
volume.setInstanceId(server.getInstanceId());
|
||||
volume.setTemplateId(dbVolumeTemplateOpt.isPresent() ? dbVolumeTemplateOpt.get().getId() : null);
|
||||
volume.setCreatorId(context.getTarget());
|
||||
volume.setGmtCreate(new Date());
|
||||
volume.setRegionId(server.getRegionId());
|
||||
volume.setRegion(server.getRegionId());
|
||||
volumeRepository.save(volume);
|
||||
}
|
||||
}
|
||||
cloudTowerTransporter.syncServerVolume(server, volumeModels, context.getTarget());
|
||||
|
||||
return new BocloudResult<>(true, server, "success");
|
||||
} catch (Exception e) {
|
||||
logger.error("Build cloudTower云主机失败:{}", e.getMessage(), e);
|
||||
return new BocloudResult<>(false, server, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.bocloud.ims.service.engine;
|
||||
|
||||
import com.bocloud.cmp.model.common.AssignResult;
|
||||
import com.bocloud.ims.entity.resource.DataStore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class AssignResultManager {
|
||||
private AssignResult assignResult;
|
||||
private Map<Long, Long> dataStoreSpaceCache = new HashMap<>();
|
||||
|
||||
public void save(List<DataStore> dataStoreList){
|
||||
dataStoreSpaceCache.clear();
|
||||
for (DataStore dataStore : dataStoreList) {
|
||||
dataStoreSpaceCache.put(dataStore.getId(), dataStore.getSpaceRemain());
|
||||
}
|
||||
}
|
||||
|
||||
public void rollback(List<DataStore> dataStoreList){
|
||||
for (DataStore dataStore : dataStoreList) {
|
||||
dataStore.setSpaceRemain(dataStoreSpaceCache.get(dataStore.getId()));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,13 +2,20 @@ package com.bocloud.ims.service.engine;
|
|||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.bocloud.cmp.driver.compute.HostDriver;
|
||||
import com.bocloud.cmp.driver.storage.DataStoreDriver;
|
||||
import com.bocloud.cmp.entity.enums.BocloudStatus;
|
||||
import com.bocloud.cmp.entity.enums.CloudProvider;
|
||||
import com.bocloud.cmp.entity.enums.PoolGroupTarget;
|
||||
import com.bocloud.cmp.model.DataStoreModel;
|
||||
import com.bocloud.cmp.model.HostOperateModel;
|
||||
import com.bocloud.cmp.model.common.AssignDataDiskParam;
|
||||
import com.bocloud.cmp.model.common.AssignDataDiskResult;
|
||||
import com.bocloud.cmp.model.common.AssignParam;
|
||||
import com.bocloud.cmp.model.common.AssignResult;
|
||||
import com.bocloud.common.model.BocloudResult;
|
||||
import com.bocloud.common.utils.ListTool;
|
||||
import com.bocloud.entity.bean.GenericEntity;
|
||||
import com.bocloud.ims.entity.resource.*;
|
||||
import com.bocloud.ims.interfaces.resource.VMExtendService;
|
||||
import com.bocloud.ims.repository.resource.*;
|
||||
|
@ -19,9 +26,11 @@ import org.slf4j.LoggerFactory;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
|
@ -51,6 +60,7 @@ import java.util.stream.Collectors;
|
|||
@Autowired private SwitcherRepository switcherRepository;
|
||||
@Autowired private NetworkHostRepository networkHostRepository;
|
||||
@Autowired private VMExtendService vmExtendService;
|
||||
@Autowired private HostDriver hostDriver;
|
||||
|
||||
/**
|
||||
* 分配数据存储
|
||||
|
@ -580,4 +590,613 @@ import java.util.stream.Collectors;
|
|||
return new BocloudResult<>(true, targetObjs, "success");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通用的调度方法
|
||||
*
|
||||
* @param assignParamList
|
||||
* @return
|
||||
*/
|
||||
public List<AssignResult> assign(PoolGroup group, CloudVendor vendor, List<AssignParam> assignParamList) throws Exception {
|
||||
// 查询策略是否存在
|
||||
SchedulerPolicy schedulerPolicy = schedulerPolicyRepository.query(group.getPolicyId());
|
||||
Assert.notNull(schedulerPolicy, "策略不存在");
|
||||
|
||||
// 过滤出资源池下关联的主机和数据存储
|
||||
List<PoolGroupRelation> relations = relationRepository.listByGroupId(group.getId());
|
||||
|
||||
|
||||
Set<Long> clusterIds = relations.stream().filter(PoolGroupRelation::getEnabled)
|
||||
.filter(relation -> PoolGroupTarget.Cluster.name().equalsIgnoreCase(relation.getCategory()))
|
||||
.map(PoolGroupRelation::getTarget)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
//查询可以调度的宿主机
|
||||
List<Server> hostList = serverRepository.queryProxy()
|
||||
.col(GenericEntity::getStatus).eq(BocloudStatus.Server.RUNNING.name())
|
||||
.col(Server::getClusterId).in(clusterIds).col(GenericEntity::getDeleted).notEq(1)
|
||||
.list();
|
||||
|
||||
String sort = "Memory";
|
||||
List<AssignResult> resultObjs = configAndAssign(sort, group.getRelationType(), SchedulerPolicy.policy.valueOf(schedulerPolicy.getPolicy()), vendor, assignParamList, hostList);
|
||||
return resultObjs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 该方法抽象出来是为了能够让获取不到资源池的场景可以调用,可以自定义调度参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<AssignResult> configAndAssign(String sort, String resourceRelationType, SchedulerPolicy.policy schedulerPolicy, CloudVendor vendor, List<AssignParam> assignParamList, List<Server> hostList) {
|
||||
configVendor(vendor, hostList);
|
||||
// logger.info("hostList:{}", JSON.toJSONString(hostList));
|
||||
|
||||
//查询ServerConfig
|
||||
configHosts(hostList);
|
||||
// logger.info("hostList:{}", JSON.toJSONString(hostList));
|
||||
|
||||
//查询宿主机下的虚拟机
|
||||
associateHostVms(hostList);
|
||||
// logger.info("hostList:{}", JSON.toJSONString(hostList));
|
||||
|
||||
//关联宿主机下的存储
|
||||
associateHostDataStores(hostList);
|
||||
// logger.info("hostList:{}", JSON.toJSONString(hostList));
|
||||
|
||||
hostList = calculateHostsRemainingResource(vendor, hostList);
|
||||
logger.info("资源变更分配宿主机列表:{}", JSON.toJSONString(hostList));
|
||||
List<AssignResult> resultObjs = doAssign(sort, assignParamList, resourceRelationType, schedulerPolicy, hostList);
|
||||
logger.info("resultObjs:{}", JSON.toJSONString(resultObjs));
|
||||
return resultObjs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 默认调用此方法前已经完成了剩余资源的计算
|
||||
* 按照DataStore的大小,从大到小排列,获取最大的存储空间创建磁盘
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private AssignResult assignSystemAndDataDiskStore(AssignParam assignParam, Server server) {
|
||||
AssignResultManager assignResultManager = new AssignResultManager();
|
||||
AssignResult assignResult = new AssignResult();
|
||||
assignResult.setSuccess(false);
|
||||
//获取计算过最新剩余大小的存储,且应该都是可用的
|
||||
List<DataStore> dataStoreList = server.getDataStores();
|
||||
assignResultManager.save(dataStoreList);
|
||||
//按照剩余空间从大到小排
|
||||
dataStoreList.sort((o1, o2) -> o2.getSpaceRemain().compareTo(o1.getSpaceRemain()));
|
||||
|
||||
for (DataStore dataStore : dataStoreList) {
|
||||
if (dataStore.getSpaceRemain() > assignParam.getDisk()) {
|
||||
dataStore.setSpaceRemain(dataStore.getSpaceRemain() - assignParam.getDisk());
|
||||
assignResult.setStoreId(dataStore.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//系统盘分配出来了才继续往下分配
|
||||
if (assignResult.getStoreId() != null) {
|
||||
|
||||
List<AssignDataDiskParam> dataDiskParams = assignParam.getDataDiskParams();
|
||||
List<AssignDataDiskResult> assignDataDiskResultList = new ArrayList<>();
|
||||
if (!CollectionUtils.isEmpty(dataDiskParams)) {
|
||||
for (AssignDataDiskParam dataDiskParam : dataDiskParams) {
|
||||
//每次都重新排序获取最大的存储
|
||||
dataStoreList.sort((o1, o2) -> o2.getSpaceRemain().compareTo(o1.getSpaceRemain()));
|
||||
|
||||
for (DataStore dataStore : dataStoreList) {
|
||||
if (dataStore.getSpaceRemain() > dataDiskParam.getSize()) {
|
||||
//保存storeName
|
||||
dataStore.setSpaceRemain(dataStore.getSpaceRemain() - dataDiskParam.getSize());
|
||||
AssignDataDiskResult diskResult = new AssignDataDiskResult();
|
||||
diskResult.setHostId(server.getId());
|
||||
diskResult.setStoreId(dataStore.getId());
|
||||
diskResult.setSize(dataDiskParam.getSize());
|
||||
diskResult.setStoreName(dataStore.getName());
|
||||
diskResult.setStoreDeviceUuid(dataStore.getGuid());
|
||||
//设置关联的申请参数
|
||||
diskResult.setAssignDataDiskParam(dataDiskParam);
|
||||
assignDataDiskResultList.add(diskResult);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assignResult.setAssignDataDiskResultList(assignDataDiskResultList);
|
||||
//申请数量和分配数量一致才算成功
|
||||
if (!CollectionUtils.isEmpty(dataDiskParams)) {
|
||||
assignResult.setSuccess(dataDiskParams.size() == assignDataDiskResultList.size());
|
||||
} else {
|
||||
assignResult.setSuccess(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//分配失败,回滚空间
|
||||
if (!assignResult.getSuccess()) {
|
||||
assignResultManager.rollback(dataStoreList);
|
||||
}
|
||||
return assignResult;
|
||||
}
|
||||
|
||||
|
||||
private <T> void sortCommon(List<T> resource, String sort, Boolean reverse, Function<T, Long> getCpuRemainder, Function<T, Long> getMemoryRemainder, Function<T, Long> getDiskRemainder) {
|
||||
Collections.sort(resource, (first, second) -> {
|
||||
if (null == first || second == null) {
|
||||
return 0;
|
||||
}
|
||||
Long preCpuRemainder = getCpuRemainder.apply(first);
|
||||
Long preMemRemainder = getMemoryRemainder.apply(first);
|
||||
Long preDiskRemainder = getDiskRemainder.apply(first);
|
||||
Long nextCpuRemainder = getCpuRemainder.apply(second);
|
||||
Long nextMemRemainder = getCpuRemainder.apply(second);
|
||||
Long nextDiskRemainder = getCpuRemainder.apply(second);
|
||||
if (reverse) {
|
||||
preCpuRemainder = getCpuRemainder.apply(second);
|
||||
preMemRemainder = getCpuRemainder.apply(second);
|
||||
preDiskRemainder = getCpuRemainder.apply(second);
|
||||
nextCpuRemainder = getCpuRemainder.apply(first);
|
||||
nextMemRemainder = getMemoryRemainder.apply(first);
|
||||
nextDiskRemainder = getMemoryRemainder.apply(first);
|
||||
}
|
||||
if ("Cpu".equalsIgnoreCase(sort)) {
|
||||
return nextCpuRemainder.compareTo(preCpuRemainder);
|
||||
} else if ("Memory".equalsIgnoreCase(sort)) {
|
||||
return nextMemRemainder.compareTo(preMemRemainder);
|
||||
} else if ("Disk".equalsIgnoreCase(sort)) {
|
||||
return nextDiskRemainder.compareTo(preDiskRemainder);
|
||||
} else {
|
||||
return nextCpuRemainder.compareTo(preCpuRemainder);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void sortWithType(List<Server> hosts, String sort, Boolean reverse, String type) {
|
||||
if (type != null) {
|
||||
type = type.toLowerCase();
|
||||
//根据不同资源类型进行分散分配
|
||||
switch (type) {
|
||||
case "cluster":
|
||||
Map<Long, List<Server>> clusterGroup = hosts.stream().collect(Collectors.groupingBy(Server::getClusterId));
|
||||
//宿主机按照集群分组
|
||||
List<Cluster> clusterList = clusterGroup.keySet().stream().map(clusterId -> {
|
||||
List<Server> servers = clusterGroup.get(clusterId);
|
||||
Cluster cluster = new Cluster();
|
||||
cluster.setId(clusterId);
|
||||
cluster.setCpuRemainder(servers.stream().mapToLong(Server::getCpuRemainder).sum());
|
||||
cluster.setMemoryRemainder(servers.stream().mapToLong(Server::getMemoryRemainder).sum());
|
||||
cluster.setDiskRemainder(servers.stream().mapToLong(Server::getDiskRemainder).sum());
|
||||
cluster.setHostNum(servers.size());
|
||||
//排序集群下宿主机
|
||||
sort(servers, sort, reverse);
|
||||
cluster.setServers(servers);
|
||||
|
||||
return cluster;
|
||||
}).collect(Collectors.toList());
|
||||
//先排序集群
|
||||
sortCommon(clusterList, sort, reverse, Cluster::getCpuRemainder, Cluster::getMemoryRemainder, Cluster::getDiskRemainder);
|
||||
|
||||
//按照集群维度分散分配
|
||||
int maxSize = clusterList.stream().mapToInt(Cluster::getHostNum).max().orElse(0);
|
||||
|
||||
|
||||
List<Server> newHosts = new ArrayList<>();
|
||||
for (int i = 0; i < maxSize; i++) {
|
||||
for (Cluster cluster : clusterList) {
|
||||
if (!CollectionUtils.isEmpty(cluster.getServers())) {
|
||||
//每次获取剩余资源最大的宿主机
|
||||
Server server = cluster.getServers().remove(0);
|
||||
newHosts.add(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
//为了适配上层调用,这里暂时只能使用这种方式改变排序结果
|
||||
hosts.clear();
|
||||
hosts.addAll(newHosts);
|
||||
break;
|
||||
case "vdc":
|
||||
Map<Long, List<Server>> vdcGroup = hosts.stream().collect(Collectors.groupingBy(Server::getVdcId));
|
||||
//宿主机按照集群分组
|
||||
List<Vdc> vdcList = vdcGroup.keySet().stream().map(vdcId -> {
|
||||
List<Server> servers = vdcGroup.get(vdcId);
|
||||
Vdc vdc = new Vdc();
|
||||
vdc.setId(vdcId);
|
||||
vdc.setCpuRemainder(servers.stream().mapToLong(Server::getCpuRemainder).sum());
|
||||
vdc.setMemoryRemainder(servers.stream().mapToLong(Server::getMemoryRemainder).sum());
|
||||
vdc.setDiskRemainder(servers.stream().mapToLong(Server::getDiskRemainder).sum());
|
||||
vdc.setHostNum((long) servers.size());
|
||||
vdc.setServers(servers);
|
||||
return vdc;
|
||||
}).collect(Collectors.toList());
|
||||
//先排序集群
|
||||
sortCommon(vdcList, sort, reverse, Vdc::getCpuRemainder, Vdc::getMemoryRemainder, Vdc::getDiskRemainder);
|
||||
|
||||
//按照VDC维度分散分配
|
||||
long maxVdcHosts = vdcList.stream().mapToLong(Vdc::getHostNum).max().orElse(0);
|
||||
List<Server> newVdcHost = new ArrayList<>();
|
||||
for (int i = 0; i < maxVdcHosts; i++) {
|
||||
for (Vdc vdc : vdcList) {
|
||||
if (i < vdc.getHostNum()) {
|
||||
Server server = vdc.getServers().get(i);
|
||||
newVdcHost.add(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
//为了适配上层调用,这里暂时只能使用这种方式改变排序结果
|
||||
hosts.clear();
|
||||
hosts.addAll(newVdcHost);
|
||||
break;
|
||||
case "host":
|
||||
default:
|
||||
this.sort(hosts, sort, reverse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<AssignResult> doAssign(String sort, List<AssignParam> assignParamList, String resourceRelationType, SchedulerPolicy.policy policy, List<Server> hosts) {
|
||||
List<AssignResult> assignResults = new ArrayList<>();
|
||||
long cpuNeed = assignParamList.stream().mapToLong(param -> param.getCpu() * param.getInstance()).sum();
|
||||
long memoryNeed = assignParamList.stream().mapToLong(param -> param.getMemory() * param.getInstance()).sum();
|
||||
switch (policy) {
|
||||
case focus:
|
||||
// 对集群进行排序,如果用户选择资源密集型策略,则倒叙排列,然后取资源剩余最适合分配的那个集群,否则正序排列
|
||||
this.sort(hosts, sort, true);
|
||||
// 资源集中式分配,不用考虑具体规格(CPU,内存等)
|
||||
for (Server host : hosts) {
|
||||
logger.info("getCpuRemainder:" + host.getCpuRemainder());
|
||||
logger.info("getMemoryRemainder:" + host.getMemoryRemainder());
|
||||
logger.info("cpuNeed:" + cpuNeed);
|
||||
logger.info("memoryNeed:" + memoryNeed);
|
||||
if (cpuNeed <= host.getCpuRemainder()
|
||||
&& memoryNeed <= host.getMemoryRemainder()) {
|
||||
logger.info("");
|
||||
for (AssignParam assignParam : assignParamList) {
|
||||
AssignResult assignResult = new AssignResult();
|
||||
assignResult.setHostId(host.getId());
|
||||
assignResult.setVdcId(host.getVdcId());
|
||||
assignResult.setClusterId(host.getClusterId());
|
||||
AssignResult result = assignSystemAndDataDiskStore(assignParam, host);
|
||||
Assert.isTrue(result.getSuccess(), "存储资源不足分配失败");
|
||||
assignResult.setAssignId(assignParam.getUuid());
|
||||
assignResult.setAssignParam(assignParam);
|
||||
assignResults.add(assignResult);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case dispersion:
|
||||
//与宿主机剩余资源排序保持一致,则剩余资源最大的宿主可以匹配占用资源最大的虚拟机
|
||||
this.sortCommon(assignParamList, sort, false, AssignParam::getCpu, AssignParam::getMemory, AssignParam::getDisk);
|
||||
this.sortWithType(hosts, sort, false, resourceRelationType);
|
||||
for (AssignParam assignParam : assignParamList) {
|
||||
assignParam.setRemain(assignParam.getInstance());
|
||||
}
|
||||
int retryCount = 0;
|
||||
for (int i = 0; i < hosts.size() && retryCount < hosts.size() && assignResults.size() < assignParamList.size(); i++) {
|
||||
Server host = hosts.get(i);
|
||||
Long cpuRemainder = host.getCpuRemainder();
|
||||
Long memoryRemainder = host.getMemoryRemainder();
|
||||
boolean assigned = false;
|
||||
// if (host.getVmRemainder() > 0) {
|
||||
for (AssignParam assignParam : assignParamList) {
|
||||
//判断宿主机剩余资源是否足够
|
||||
if (assignParam.getRemain() > 0
|
||||
&& assignParam.getCpu() <= cpuRemainder
|
||||
&& assignParam.getMemory() <= memoryRemainder) {
|
||||
AssignResult assignResult = this.assignSystemAndDataDiskStore(assignParam, host);
|
||||
if (!assignResult.getSuccess()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assignResult.setHostId(host.getId());
|
||||
assignResult.setVdcId(host.getVdcId());
|
||||
assignResult.setAssignId(assignParam.getUuid());
|
||||
assignResult.setAssignParam(assignParam);
|
||||
assignResult.setClusterId(host.getClusterId());
|
||||
assignResults.add(assignResult);
|
||||
host.setCpuRemainder(cpuRemainder - assignParam.getCpu());
|
||||
host.setMemoryRemainder(memoryRemainder - assignParam.getMemory());
|
||||
|
||||
assignParam.setRemain(assignParam.getRemain() - 1);
|
||||
// host.setVmRemainder(host.getVmRemainder() - 1);
|
||||
assigned = true;
|
||||
//分配到一个之后就中断,分配下一个宿主机
|
||||
break;
|
||||
}
|
||||
}
|
||||
// }
|
||||
if (!assigned) {
|
||||
retryCount++;
|
||||
} else {
|
||||
retryCount = 0;
|
||||
}
|
||||
//重新回到第一个宿主机继续分配
|
||||
if (i == hosts.size() - 1) {
|
||||
i = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case random:
|
||||
Server host = hosts.get(new Random().nextInt(hosts.size()));
|
||||
for (AssignParam assignParam : assignParamList) {
|
||||
AssignResult assignResult = new AssignResult();
|
||||
assignResult.setHostId(host.getId());
|
||||
assignResult.setVdcId(host.getVdcId());
|
||||
assignResult.setClusterId(host.getClusterId());
|
||||
List<DataStore> dataStoreList = host.getDataStores();
|
||||
if (!CollectionUtils.isEmpty(dataStoreList)) {
|
||||
DataStore dataStore = dataStoreList.get(new Random().nextInt(dataStoreList.size()));
|
||||
assignResult.setStoreId(dataStore.getId());
|
||||
}
|
||||
assignResult.setAssignId(assignParam.getUuid());
|
||||
assignResult.setAssignParam(assignParam);
|
||||
assignResults.add(assignResult);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return assignResults;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void calculateHostRemain(CloudVendor cloudVendor, Server host, ServerConfig config, List<CloudServer> vms) {
|
||||
long cpuTotal;
|
||||
long memoryTotal = 0;
|
||||
//计算资源剩余统计,安超的聚合组就是集群,
|
||||
//cpu超分比默认取平台
|
||||
Long cpuExcessRatio = cloudVendor.getExcessRatio();
|
||||
|
||||
//虚拟化比
|
||||
// host.setVmRemainder(cloudVendor.getVirtualizationRatio().intValue());
|
||||
// //统一计算剩余可分配虚拟机数量
|
||||
// if (vms == null) {
|
||||
// vms = new ArrayList<>();
|
||||
// }
|
||||
// host.setVmRemainder(host.getVmRemainder() - vms.size());
|
||||
|
||||
|
||||
// 计算每个宿主机剩余可用cpu,内存,存储容量,看是否有可分配的主机
|
||||
int cpuUsed = vms.stream().mapToInt(CloudServer::getCpu).sum();
|
||||
BigDecimal memUsed = null;
|
||||
if (CloudProvider.VMWARE.name().equals(cloudVendor.getType())) {
|
||||
HostOperateModel model = new HostOperateModel();
|
||||
model.setHostName(host.getName());
|
||||
try {
|
||||
BocloudResult detail = hostDriver.detail(cloudVendor.getUuid(), null, model);
|
||||
Assert.isTrue(detail.isSuccess(), detail.getMessage());
|
||||
JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(detail.getData()));
|
||||
if (jsonObject.getBigDecimal("memUsed") != null) {
|
||||
memUsed = jsonObject.getBigDecimal("memUsed");
|
||||
memoryTotal = jsonObject.getLong("memTotal");
|
||||
logger.info("当前宿主机名称:" + host.getName() + ",已使用内存:" + memUsed + "G" + ",内存总量:" + memoryTotal + "G");
|
||||
} else {
|
||||
Assert.isTrue(false, "获取vmware宿主机详情失败");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.error("获取vmware宿主机信息失败:", e);
|
||||
Assert.isTrue(false, e.getMessage());
|
||||
}
|
||||
} else {
|
||||
memUsed = vms.stream().map(CloudServer::getMemory).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
|
||||
//内存没有超分比
|
||||
memoryTotal = null == config.getMemoryCapacity() ? 0 :
|
||||
BigDecimal.valueOf(config.getMemoryCapacity()).longValue();
|
||||
}
|
||||
|
||||
cpuTotal = BigDecimal.valueOf(config.getCpuCore()).multiply(BigDecimal.valueOf(cpuExcessRatio)).longValue();
|
||||
logger.info("cpuTotal:" + cpuTotal);
|
||||
logger.info("cpuUsed:" + cpuUsed);
|
||||
host.setCpuRemainder(Math.max(cpuTotal - cpuUsed, 0L));
|
||||
|
||||
|
||||
// //判断当前内存使用量是否超出阈值设置
|
||||
// if (BigDecimal.valueOf(memoryTotal).multiply(BigDecimal.valueOf(cloudVendor.getMemoryRatioPre())).divide(BigDecimal.valueOf(100)).compareTo(memUsed) <= 0) {
|
||||
// host.setMemoryRemainder(0L);
|
||||
// } else {
|
||||
// // 使用分配后的阈值计算可以用内存的量
|
||||
// memoryTotal = BigDecimal.valueOf(memoryTotal).multiply(BigDecimal.valueOf(cloudVendor.getMemoryRatioPost())).divide(BigDecimal.valueOf(100)).longValue();
|
||||
//
|
||||
logger.info("memoryTotal:" + memoryTotal);
|
||||
logger.info("memUsed:" + memUsed);
|
||||
host.setMemoryRemainder(Math.max(memoryTotal - memUsed.longValue(), 0L));
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
private void calculateStoreRemain(CloudVendor vendor, DataStore store) {
|
||||
// Long storageRatioPre = vendor.getStorageRatioPre();
|
||||
BigDecimal spaceUsed = BigDecimal.valueOf(store.getCapacity() - store.getFreeSpace());
|
||||
|
||||
//判断已使用空间是否小于阈值
|
||||
// if (BigDecimal.valueOf(store.getCapacity()).multiply(BigDecimal.valueOf(storageRatioPre))
|
||||
// .divide(BigDecimal.valueOf(100)).compareTo(spaceUsed) > 0) {
|
||||
//
|
||||
// //计算剩余可用容量
|
||||
// Long storageRatioPost = vendor.getStorageRatioPost();
|
||||
//可用容量
|
||||
BigDecimal availableSpace = BigDecimal.valueOf(store.getCapacity());
|
||||
|
||||
logger.info("availableSpace:" + availableSpace);
|
||||
logger.info("spaceUsed:" + spaceUsed);
|
||||
logger.info("spaceRemain" + availableSpace.subtract(spaceUsed).longValue());
|
||||
store.setSpaceRemain(availableSpace.subtract(spaceUsed).longValue());
|
||||
// } else {
|
||||
// store.setSpaceRemain(0L);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一计算宿主机剩余资源,会计算宿主机剩余计算资源,宿主机可以访问到的存储资源
|
||||
*
|
||||
* @return true表示有剩余资源,可以参与后续资源分配
|
||||
*/
|
||||
public boolean calculateHostRemainingResource(CloudVendor vendor, Server host) {
|
||||
if (!BocloudStatus.Server.RUNNING.name().equals(host.getStatus())) {
|
||||
return false;
|
||||
}
|
||||
ServerConfig config = host.getConfig();
|
||||
if (null == config) {
|
||||
return false;
|
||||
}
|
||||
|
||||
List<CloudServer> vms = host.getServers();
|
||||
calculateHostRemain(vendor, host, config, vms);
|
||||
logger.info("host:{}", JSON.toJSONString(host));
|
||||
List<DataStore> dataStoreList = host.getDataStores();
|
||||
if (host.getCpuRemainder() >= 0 && host.getMemoryRemainder() >= 0) {
|
||||
long diskTotalRemain = 0;
|
||||
if (CollectionUtils.isEmpty(dataStoreList)) {
|
||||
return false;
|
||||
}
|
||||
for (DataStore store : dataStoreList) {
|
||||
calculateStoreRemain(vendor, store);
|
||||
if (store.getSpaceRemain() > 0) {
|
||||
//统计剩余容量
|
||||
diskTotalRemain += store.getSpaceRemain();
|
||||
}
|
||||
}
|
||||
logger.info("dataStoreList:{}", JSON.toJSONString(dataStoreList));
|
||||
dataStoreList = dataStoreList.stream().filter(store -> store.getSpaceRemain() > 0).collect(Collectors.toList());
|
||||
host.setDiskRemainder(Math.max(diskTotalRemain, 0L));
|
||||
//新建存储和宿主机的关系
|
||||
List<StoreHost> storeHosts = dataStoreList.stream().map(store -> {
|
||||
StoreHost storeHost = new StoreHost();
|
||||
storeHost.setVhostId(host.getId());
|
||||
storeHost.setStoreId(store.getId());
|
||||
return storeHost;
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
//设置新的关系
|
||||
host.setStoreHosts(storeHosts);
|
||||
host.setDataStores(dataStoreList);
|
||||
return !dataStoreList.isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public List<Server> calculateHostsRemainingResource(CloudVendor vendor, Collection<Server> hosts) {
|
||||
List<Server> newHosts = new ArrayList<>();
|
||||
for (Server host : hosts) {
|
||||
// logger.info("host:{}", JSON.toJSONString(host));
|
||||
if (calculateHostRemainingResource(vendor, host)) {
|
||||
newHosts.add(host);
|
||||
}
|
||||
}
|
||||
return newHosts;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 配置云平台指标
|
||||
*
|
||||
* @param cloudVendor
|
||||
* @param hosts
|
||||
*/
|
||||
public void configVendor(CloudVendor cloudVendor, List<Server> hosts) {
|
||||
JSONObject authentication = JSONObject.parseObject(cloudVendor.getAuthentication());
|
||||
cloudVendor.setExcessRatio(Optional.ofNullable(authentication.getLong("excessRatio")).orElse(100L));
|
||||
// cloudVendor.setVirtualizationRatio(Optional.ofNullable(authentication.getLong("virtualizationRatio")).orElse(100L));
|
||||
// cloudVendor.setMemoryRatioPost(Optional.ofNullable(authentication.getLong("memoryRatioPost")).orElse(85L));
|
||||
// cloudVendor.setMemoryRatioPre(Optional.ofNullable(authentication.getLong("memoryRatioPre")).orElse(80L));
|
||||
// cloudVendor.setStorageRatioPost(Optional.ofNullable(authentication.getLong("storageRatioPost")).orElse(85L));
|
||||
// cloudVendor.setStorageRatioPre(Optional.ofNullable(authentication.getLong("storageRatioPre")).orElse(80L));
|
||||
for (Server host : hosts) {
|
||||
host.setVendor(cloudVendor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 将宿主机的配置设置到config字段
|
||||
*/
|
||||
public void configHosts(Collection<Server> hosts) {
|
||||
// 统一查询宿主机
|
||||
Set<Long> hostIds = hosts.stream().map(Server::getId).collect(Collectors.toSet());
|
||||
List<ServerConfig> list = null;
|
||||
if (hostIds.isEmpty()) {
|
||||
list = new ArrayList<>();
|
||||
} else {
|
||||
list = serverConfigRepository.queryProxy().col(ServerConfig::getServerId).in(hostIds).list();
|
||||
}
|
||||
Map<Long, ServerConfig> hostIdMapConfig = list.stream().collect(Collectors.toMap(ServerConfig::getServerId, Function.identity(), (f, s) -> f));
|
||||
for (Server host : hosts) {
|
||||
host.setConfig(hostIdMapConfig.get(host.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void associateHostVms(Collection<Server> hosts) {
|
||||
Set<Long> hostIds = hosts.stream().map(Server::getId).collect(Collectors.toSet());
|
||||
Assert.notEmpty(hostIds, "资源池中没有合适的宿主机");
|
||||
//统一查询虚拟机
|
||||
List<CloudServer> cloudServerList = cloudServerRepository.queryProxy()
|
||||
.col(CloudServer::getHostId).in(hostIds)
|
||||
.col(GenericEntity::getDeleted).notEq(1)
|
||||
.col(CloudServer::getIsTemplate).notEq(1)
|
||||
// 只查询活动状态下的虚拟机进行计算
|
||||
.col(CloudServer::getStatus).in("BUILDING", "RUNNING")
|
||||
.list();
|
||||
logger.info("当前所有宿主机: {},下的虚拟机信息:{}", JSON.toJSONString(hostIds), JSON.toJSONString(cloudServerList));
|
||||
Map<Long, List<CloudServer>> cloudServerMap = cloudServerList.stream().collect(Collectors.groupingBy(CloudServer::getHostId));
|
||||
for (Server host : hosts) {
|
||||
host.setServers(cloudServerMap.get(host.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 关联主机存储
|
||||
* 该方法是为了统计最新的存储状态
|
||||
* 并将宿主机的dataStores字段赋值
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public void associateHostDataStores(Collection<Server> hosts) {
|
||||
/** 处理存储关联关系,由于cloudTower超融合没有单独存储,存储挂在主机下面可以模拟创建一个dataStore对象,每台宿主机有一个存储对象
|
||||
后续进行dataStore分配的时候需要通过存储对象来调度,vc是每个宿主机挂载多个存储,安超和cloudTower需要适配mock出宿主机和存储的关联关系
|
||||
**/
|
||||
Map<Long, List<Server>> vendorMapHosts = hosts.stream().collect(Collectors.groupingBy(Server::getVendorId));
|
||||
for (Map.Entry<Long, List<Server>> entry : vendorMapHosts.entrySet()) {
|
||||
List<Server> hostList = entry.getValue();
|
||||
CloudVendor vendor = hostList.get(0).getVendor();
|
||||
CloudProvider provider = CloudProvider.valueOf(vendor.getType());
|
||||
|
||||
List<Long> hostIds = hostList.stream().map(Server::getId).collect(Collectors.toList());
|
||||
switch (provider) {
|
||||
// case VMWARE:
|
||||
// associateVmwareHostsDataStore(hosts, vendor, hostIds);
|
||||
// break;
|
||||
case CLOUDTOWER:
|
||||
associateCloudTowerHostsDataStore(hostList);
|
||||
break;
|
||||
// case ARCHEROS:
|
||||
// associatArcherOsHostsDataStore(hostList);
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void associateCloudTowerHostsDataStore(List<Server> hostList) {
|
||||
for (Server server : hostList) {
|
||||
ServerConfig config = server.getConfig();
|
||||
DataStore dataStore = new DataStore();
|
||||
//设置一个模拟的id,负数Id不会和数据库中的冲突
|
||||
dataStore.setId(-new Random().nextLong());
|
||||
dataStore.setCapacity(config.getDiskCapacity().longValue());
|
||||
dataStore.setFreeSpace(config.getDiskCapacity().longValue() - config.getDiskUsed().longValue());
|
||||
server.setDataStores(Arrays.asList(dataStore));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.bocloud.cmp.entity.enums.ResourceCategory;
|
|||
import com.bocloud.cmp.model.*;
|
||||
import com.bocloud.cmp.model.common.*;
|
||||
import com.bocloud.cmp.model.common.OrderMessage.Operation;
|
||||
import com.bocloud.cmp.vm.model.CloudTowerDisk;
|
||||
import com.bocloud.cmp.vm.model.VmGenericParam;
|
||||
import com.bocloud.common.encrypt.AESEncrptor;
|
||||
import com.bocloud.common.encrypt.Encryptor;
|
||||
|
@ -410,6 +411,46 @@ public class VMApplyServiceImpl implements VMApplyService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// assignMapTarget = new HashMap<>();
|
||||
List<AssignResult> assignParamListBak = new ArrayList<>();
|
||||
//ct分配资源
|
||||
if (provider == CloudProvider.CLOUDTOWER) {
|
||||
List<AssignParam> assignParamList = new ArrayList<>();
|
||||
AssignParam assignParam = param.getAssignParam();
|
||||
//设置系统盘
|
||||
assignParam.setDisk(assignParam.getTemplateDisk());
|
||||
|
||||
//处理数据盘
|
||||
List<CloudTowerDisk> cloudTowerDisks = Optional.ofNullable(assignParam.getOriginalConfigs()).map(c -> c.getJSONArray("volumeModels")).map(a -> a.toJavaList(CloudTowerDisk.class)).orElse(new ArrayList<>());
|
||||
|
||||
//设置数据盘申请参数
|
||||
List<AssignDataDiskParam> dataDiskParams = cloudTowerDisks.stream().map(AssignDataDiskParam::new).collect(Collectors.toList());
|
||||
assignParam.setDataDiskParams(dataDiskParams);
|
||||
|
||||
assignParamList.add(assignParam);
|
||||
PoolGroup poolGroup = poolGroupRepository.query(location.getPoolGroupId());
|
||||
|
||||
List<AssignResult> assignResultList = resSchedulerEngine.assign(poolGroup, vendor, assignParamList);
|
||||
|
||||
Map<String, List<AssignResult>> assignMapTarget = assignResultList.stream().collect(Collectors.groupingBy(obj -> {
|
||||
String assignId = obj.getAssignId();
|
||||
if (assignId == null) {
|
||||
assignId = "";
|
||||
}
|
||||
return assignId;
|
||||
}));
|
||||
|
||||
|
||||
Assert.notEmpty(assignMapTarget, "云主机调度失败");
|
||||
//如果有uuid关联的分配结果则一般为反亲和
|
||||
if (assignMapTarget.containsKey(assignParam.getUuid())) {
|
||||
assignParamListBak = assignMapTarget.get(assignParam.getUuid());
|
||||
} else {//如果没有uuid关联的分配结果,则为随机或者亲和
|
||||
assignParamListBak = assignMapTarget.get("");
|
||||
}
|
||||
}
|
||||
|
||||
if (CloudProvider.VMWARE == provider) {
|
||||
BocloudResult<List<JSONObject>> bocloudResult = null;
|
||||
// 如果没有使用计算资源池,则默认按照随机策略分配宿主机和存储
|
||||
|
@ -493,6 +534,7 @@ public class VMApplyServiceImpl implements VMApplyService {
|
|||
}
|
||||
}
|
||||
|
||||
logger.info("分配后的IP信息:" + JSON.toJSONString(configs.getString("networkCardConfigs")));
|
||||
|
||||
if (provider.equals(CloudProvider.SANGFOR) && "6.8".equals(vendor.getVersion())){
|
||||
//获取资源池Id
|
||||
|
@ -519,7 +561,7 @@ public class VMApplyServiceImpl implements VMApplyService {
|
|||
JSONArray networkCardConfigs1 = configs.getJSONArray("networkCardConfigs");
|
||||
for (Object netWork : networkCardConfigs1){
|
||||
JSONObject jsonObject = (JSONObject) netWork;
|
||||
JSONArray address = jsonObject.getJSONArray("address");
|
||||
JSONArray address = provider.equals(CloudProvider.CLOUDTOWER) ? jsonObject.getJSONArray("ipAddress") : jsonObject.getJSONArray("address");
|
||||
Long ipPoolId = jsonObject.getLong("ipPoolId");
|
||||
if (address.isEmpty()) {
|
||||
BocloudResult<List<Ip>> listBocloudResult = ipService.achievePoolIps(ipPoolId, count.longValue(), null);
|
||||
|
@ -550,7 +592,7 @@ public class VMApplyServiceImpl implements VMApplyService {
|
|||
for (Object object : networkCardConfigs) {
|
||||
JSONObject jsonObject = (JSONObject) object;
|
||||
BocloudResult<User> userDetail = smsUserService.detail(location.getCreatorId());
|
||||
newObj.put("name", jsonObject.getJSONArray("address").get(i) +"-"+ userDetail.getData().getName() +"-"+purpose);
|
||||
newObj.put("name", (provider.equals(CloudProvider.CLOUDTOWER) ? jsonObject.getJSONArray("ipAddress") : jsonObject.getJSONArray("address")).get(i) + "-" + userDetail.getData().getName() + "-" + purpose);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -603,6 +645,26 @@ public class VMApplyServiceImpl implements VMApplyService {
|
|||
}
|
||||
|
||||
|
||||
if (!ListTool.isEmpty(assignParamListBak)) {
|
||||
|
||||
AssignResult targetObj = assignParamListBak.get(i);
|
||||
//设置宿主机,系统盘存储位置
|
||||
newObj.put("storeId", targetObj.getStoreId());
|
||||
newObj.put("hostId", targetObj.getHostId());
|
||||
newObj.put("vdcId", targetObj.getVdcId());
|
||||
//冗余一个宿主机ID,cloudTower通过serverId来控制磁盘
|
||||
newObj.put("serverId", targetObj.getHostId());
|
||||
newObj.put("clusterId", targetObj.getClusterId());
|
||||
|
||||
//这个属性创建时暂时没有找到使用的地方,后续可以考虑删除
|
||||
newObj.put("dataDiskList", newObj.getString("addDiskList"));
|
||||
newObj.put("diskDevices", newObj.get("volumeModels"));
|
||||
newObj.put("networkCards", newObj.get("networkCardConfigs"));
|
||||
// 暂时注释,解决没有数据盘问题
|
||||
// newObj.remove("addDiskList");
|
||||
|
||||
}
|
||||
|
||||
if (!ListTool.isEmpty(targetObjs)) {
|
||||
JSONObject targetObj = targetObjs.get(i);
|
||||
if (hostId != null && hostId.longValue() > 0L) {
|
||||
|
@ -680,6 +742,15 @@ public class VMApplyServiceImpl implements VMApplyService {
|
|||
} else if (CloudProvider.SANGFOR == provider){
|
||||
result = serverOperationHelper.prepareSangfor(object, param.getContext(), vendor, process, indexInSpec, size);
|
||||
} else {
|
||||
|
||||
if (CloudProvider.CLOUDTOWER == provider) {
|
||||
//ct的特殊处理
|
||||
JSONArray networkCardConfigs = object.getJSONArray("networkCardConfigs");
|
||||
for (Object networkCardConfig : networkCardConfigs) {
|
||||
JSONObject jsonObject = (JSONObject) networkCardConfig;
|
||||
jsonObject.put("ipAddress", jsonObject.getJSONArray("ipAddress").get(indexInSpec));
|
||||
}
|
||||
}
|
||||
result = serverOperationHelper.prepare(
|
||||
JSONObject.parseObject(object.toJSONString(), VmGenericParam.class), param.getContext(), vendor,
|
||||
process);
|
||||
|
|
Loading…
Reference in New Issue