Compare commits

...

16 Commits

Author SHA1 Message Date
guyuliang d65c979618 修复ct申请虚拟机流程 2024-05-31 11:20:43 +08:00
guyuliang e01c5d06c7 修复ct申请虚拟机流程 2024-05-31 11:04:19 +08:00
guyuliang e9d69a7a47 修复ct申请虚拟机流程 2024-05-31 10:57:59 +08:00
guyuliang 4a4161c71b ct查询ip接口 2024-05-30 18:27:17 +08:00
guyuliang 4cc086835a ct查询ip接口 2024-05-30 18:22:18 +08:00
bayuzhen 1876740e27 处理大屏展示资源使用情况问题 2024-05-30 16:47:28 +08:00
bayuzhen b24022e835 处理大屏展示资源使用情况问题 2024-05-30 15:56:28 +08:00
bayuzhen deef8d99f1 处理大屏展示资源使用情况问题 2024-05-30 15:39:22 +08:00
bayuzhen 273988a5f8 处理大屏展示资源使用情况问题 2024-05-30 15:08:38 +08:00
bayuzhen 185d1cd9ad 处理大屏展示资源使用情况问题 2024-05-30 15:00:22 +08:00
guyuliang 4b6bf6bb54 cloudTower申请虚拟机流程 2024-05-29 16:13:51 +08:00
bayuzhen 3116e622ef 迁移cloudTower监控告警 2024-05-28 18:37:47 +08:00
guyuliang ac490ab0ea 添加ct的transporter 2024-05-28 15:21:14 +08:00
bayuzhen 12dac071a5 添加日志 2024-05-24 12:04:32 +08:00
bayuzhen 2647af89aa 添加达梦sql文件 2024-05-23 15:48:44 +08:00
Hoshi 2338a7eedc fix 2024-05-22 20:16:13 +08:00
31 changed files with 2885 additions and 27 deletions

BIN
HBCL_DM8.dmp Normal file

Binary file not shown.

View File

@ -27,15 +27,15 @@ spring:
discovery:
register: true
enable: true
instance-host: 10.40.20.48
instance-host: 127.0.0.1
instance-port: ${server.port}
root: ${spring.cloud.zookeeper.home}/services
datasource:
druid:
dialect: mysql
url: jdbc:mysql://10.20.12.56:3306/cmp?characterEncoding=utf8&useSSL=false
dialect: dm
url: jdbc:dm://23.33.3.28:5236/cmp?characterEncoding=utf8&useSSL=false
username: cmp
password: Gy2VghUgWHszx8gLFT4etT9ZVOukJi73KoG1q3Oz/DAz5h2mFVVunjcyaaKT9tMPsBgoWBFRmrYbhgqJqT/Q8A==
password: BoYunCmp@v587
initialSize: '2'
maxActive: '30'
minIdle: '2'
@ -54,12 +54,12 @@ spring:
timeBetweenEvictionRunsMillis: '10000'
minEvictableIdleTimeMillis: '30001'
asyncCloseConnectionEnable: 'true'
filters: config,stat,wall,log4j
filters: config,stat,log4j
publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJfVJOpXYGy8aBCk3zEoKKQDTVCCvJwhhithfY/I5PUvzFBAYygunmuCtUhzPUZ+1RJQds0Q4fu07m5mr5kv5ocCAwEAAQ==
connectionProperties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJfVJOpXYGy8aBCk3zEoKKQDTVCCvJwhhithfY/I5PUvzFBAYygunmuCtUhzPUZ+1RJQds0Q4fu07m5mr5kv5ocCAwEAAQ==;druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
connectionProperties: config.decrypt=false;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJfVJOpXYGy8aBCk3zEoKKQDTVCCvJwhhithfY/I5PUvzFBAYygunmuCtUhzPUZ+1RJQds0Q4fu07m5mr5kv5ocCAwEAAQ==;druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
use-global-data-source-stat: 'true'
rabbitmq:
host: 10.20.12.56
host: 23.33.3.28
port: 5672
username: admin
password: BOCLOUD@CoU6oY/zuAoBbu6cdgOKlA==
@ -71,7 +71,7 @@ spring:
checkTemplateLocation: 'false'
redis:
# standalone
host: 10.20.12.56
host: 23.33.3.28
port: 6379
timeout: 60000ms
password: BOCLOUD@CoU6oY/zuAoBbu6cdgOKlA==
@ -89,7 +89,7 @@ spring:
allow-circular-references: true
zk:
server:
url: 10.20.12.56:2181
url: 127.0.0.1:2181
username: bocloud
password: BOCLOUD@CoU6oY/zuAoBbu6cdgOKlA==
conn:
@ -98,7 +98,7 @@ zk:
timeout: '50000'
logging:
config: classpath:logback-spring.xml
dir: /log/services
dir: /Users/guyuliang/project/EFC
level:
root: info
com:
@ -123,3 +123,6 @@ nim:
#Cmp Repo
cmp:
repo: http://192.168.6.209/yum
regex:

View File

@ -0,0 +1,22 @@
package com.bocloud.ims.entity.model;
import com.bocloud.ims.entity.resource.Ip;
import lombok.Data;
/**
* @author zouhu
* @date 2024/3/19 11:30
*/
@Data
public class SimpleIpModel {
private Long id;
private String ip;
private String gateway;
private String dns;
private String mask;
private Long vendorId;
private Long poolId;
private Long target;
private String catalog;
private Ip.IpStatus status;
}

View File

@ -478,6 +478,12 @@ public class CloudServer extends GenericEntity implements VendorEntity {
private List<Volume> diskList;
@IgnoreAll
private String statusName;
@IgnoreAll
private String nicUuid;
@Column("local_id")
private String localId;
/**
* @return the password

View File

@ -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

View File

@ -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

View File

@ -159,6 +159,30 @@ public class Network extends GenericEntity {
@IgnoreAll
private String azName;
@Column("local_id")
private String localId;
@Column("cluster_uuid")
private String clusterUuid;
public String getClusterUuid() {
return clusterUuid;
}
public void setClusterUuid(String clusterUuid) {
this.clusterUuid = clusterUuid;
}
public String getLocalId() {
return localId;
}
public void setLocalId(String localId) {
this.localId = localId;
}
public Boolean getRouterExternal() {
return isRouterExternal;
}

View File

@ -142,6 +142,8 @@ public class Server extends GenericEntity {
@IgnoreAll
private ServerConfig config;
@IgnoreAll
private String nicUuid;
@IgnoreAll
private ServerAssets assets;
@IgnoreAll
private List<Switcher> switchers;
@ -298,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);

View File

@ -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
*/

View File

@ -190,4 +190,10 @@ public class VendorTaskMsg extends Generic {
return this.getSmartSucceed() || this.getSmartFailed();
}
public boolean getCloudTowerSucceed() {
// smart的任务状态 pending processing done failed
return "SUCCESSED".equalsIgnoreCase(this.getStatus());
}
}

View File

@ -13,6 +13,7 @@ import com.bocloud.database.core.intf.impl.BasicGenericDao;
import com.bocloud.database.utils.QueryBuilder;
import com.bocloud.ims.entity.common.MathUtils;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.orm.OrmGenericDaoImpl;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
@ -30,7 +31,7 @@ import java.util.*;
* @since 2020515
*/
@Repository("cloudVendorRepository")
public class CloudVendorRepository extends BasicGenericDao<CloudVendor, Long> {
public class CloudVendorRepository extends OrmGenericDaoImpl<CloudVendor, Long> {
public CloudVendorRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
super(jdbcTemplate, npJdbcTemplate);

View File

@ -10,6 +10,7 @@ import com.bocloud.common.utils.MapTools;
import com.bocloud.database.core.intf.impl.BasicGenericDao;
import com.bocloud.database.utils.QueryBuilder;
import com.bocloud.ims.entity.resource.Cluster;
import com.bocloud.orm.OrmGenericDaoImpl;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.JdbcTemplate;
@ -29,7 +30,7 @@ import java.util.Map;
* @since 2020515
*/
@Component("clusterRepository")
public class ClusterRepository extends BasicGenericDao<Cluster, Long> {
public class ClusterRepository extends OrmGenericDaoImpl<Cluster, Long> {
public ClusterRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
super(jdbcTemplate, npJdbcTemplate);

View File

@ -8,15 +8,19 @@ import com.bocloud.common.utils.ListTool;
import com.bocloud.common.utils.MapTools;
import com.bocloud.database.core.intf.impl.BasicGenericDao;
import com.bocloud.database.utils.QueryBuilder;
import com.bocloud.ims.entity.model.SimpleIpModel;
import com.bocloud.ims.entity.resource.Ip;
import com.bocloud.ims.entity.resource.Ip.IpStatus;
import com.bocloud.orm.OrmBasicDaoImpl;
import com.bocloud.orm.OrmGenericDaoImpl;
import com.google.common.collect.Maps;
import org.springframework.beans.BeanUtils;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -179,6 +183,23 @@ public class IpRepository extends OrmGenericDaoImpl<Ip, Long> {
return this.list(Ip.class, sql, params);
}
public List<SimpleIpModel> listByPool(Long poolId, String status) {
String sql = "select id,ip,mask,gateway,dns,vendor_id,target,catalog,pool_id,status from ip where pool_id = :poolId and status = :status";
Map<String, Object> params = MapTools.simpleMap("poolId", poolId);
params.put("status", status);
List<Ip> ips = this.list(Ip.class, sql, params);
List<SimpleIpModel> list = new ArrayList<>();
if (!ObjectUtils.isEmpty(ips)) {
for (Ip ip : ips) {
SimpleIpModel model = new SimpleIpModel();
BeanUtils.copyProperties(ip, model);
list.add(model);
}
}
return list;
}
public boolean delete(Long target, String catalog, Long vendorId) {
// 5.6版本IP池中的IP是不允许被删除掉的 #PBSM-13169 bug
// 初步怀疑是调用delete方法将IP删除导致的因为调用的地方有点多版本今天要发布所以直接修改源头后续该部分逻辑需要移到相关业务层

View File

@ -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);

View File

@ -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);

View File

@ -17,6 +17,7 @@ import com.bocloud.database.utils.QueryBuilder;
import com.bocloud.ims.entity.resource.Rack;
import com.bocloud.ims.entity.resource.Room;
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;
@ -32,7 +33,7 @@ import java.util.*;
* @since 2020515
*/
@Repository("serverRepository")
public class ServerRepository extends BasicGenericDao<Server, Long> {
public class ServerRepository extends OrmGenericDaoImpl<Server, Long> {
public ServerRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate) {
super(jdbcTemplate, npJdbcTemplate);

View File

@ -1039,4 +1039,16 @@ public class VolumeRepository extends OrmGenericDaoImpl<Volume, Long> {
List<Volume> list = this.list(Volume.class, sql, params);
return list == null || list.size() == 0 ? null : list.get(0).getSequenceNum();
}
public Volume getByServerIdAndVolumeUuid(Long serverId, String volumeUuid) {
String sql = "select a.* from volume a where a.is_deleted = 0 and a.server_id = :serverId and a.volume_uuid = :volumeUuid";
Map<String, Object> paramMap = MapTools.simpleMap("serverId", serverId);
paramMap.put("volumeUuid", volumeUuid);
List<Volume> list = this.list(Volume.class, sql, paramMap);
if (list.isEmpty()) {
return null;
}
return list.get(0);
}
}

View File

@ -104,4 +104,12 @@ public class VolumeTemplateRepository extends JdbcGenericDao<VolumeTemplate, Lon
List<VolumeTemplate> templates = list(VolumeTemplate.class, sql, params);
return templates == null || templates.size() == 0 ? null : templates.get(0);
}
public VolumeTemplate getByName(String name) {
String sql = "select a.* from volume_template a where a.is_deleted = 0 and a.name = :name";
Map<String, Object> params = MapTools.simpleMap("name", name);
List<VolumeTemplate> templates = list(VolumeTemplate.class, sql, params);
return templates == null || templates.size() == 0 ? null : templates.get(0);
}
}

View File

@ -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());
}
}
}

View File

@ -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()));
}
}
}

View File

@ -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) {
/** cloudTowerdataStore,宿
dataStorevc宿cloudTowermock宿
**/
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));
}
}
}

View File

@ -437,7 +437,19 @@ public class CloudServerServiceImpl implements CloudServerService, InitializingB
});
});
String azUuid, azName;
Map<Long, String> netMap = new HashMap<>();
CloudVendor cloudVendor = cloudVendorRepository.query(vendorId);
if (null != cloudVendor && "CLOUDTOWER".equals(cloudVendor.getType())) {
List<Long> collect = list.stream().map(CloudServer::getId).collect(Collectors.toList());
List<NetworkCard> networkCardList = networkCardRepository.queryProxy().col(NetworkCard::getHostId).in(collect)
.col(NetworkCard::getCategory).eq("VM")
.col(GenericEntity::getDeleted).eq(false).list();
netMap = networkCardList.stream().collect(Collectors.toMap(NetworkCard::getHostId, NetworkCard::getInstanceId, (existingValue, newValue) -> newValue));
}
for (CloudServer server : list) {
if (null != cloudVendor && "CLOUDTOWER".equals(cloudVendor.getType())) {
server.setNicUuid(netMap.get(server.getId()));
}
azUuid = server.getAzUuid();
if (StringUtils.isNotEmpty(azUuid)) {
azName = allAzUuidNameMap.get(azUuid);

View File

@ -15,6 +15,7 @@ import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.IDFactory;
import com.bocloud.common.utils.ListTool;
import com.bocloud.entity.bean.GenericEntity;
import com.bocloud.ims.entity.model.SimpleIpModel;
import com.bocloud.ims.entity.params.IpPatchParams;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.entity.resource.Ip.IpStatus;
@ -144,6 +145,11 @@ public class IpServiceImpl implements IpService {
} else if ("checkIp".equalsIgnoreCase(object.getString("condition"))) {
List<String> ips = JSONArray.parseArray(object.getString("ips"), String.class);
return this.checkIp(object.getLong("poolId"), ips, context);
}else if ("listByPoolAndStatus".equalsIgnoreCase(object.getString("condition"))) {
Long poolId = object.getLong("poolId");
String status = object.getString("status");
List<SimpleIpModel> ipList = ipRepository.listByPool(poolId, status);
return new BocloudResult<>(true, ipList, "查询成功");
}
return new BocloudResult<>(false, "参数格式错误");
} catch (Exception e) {

View File

@ -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;
@ -248,6 +249,21 @@ public class VMApplyServiceImpl implements VMApplyService {
Assert.notNull(vendor, "云平台不存在");
CloudProvider provider = CloudProvider.valueOf(vendor.getType());
if (provider == CloudProvider.CLOUDTOWER) {
//适配cloudTower
AssignParam assignParam = new AssignParam();
assignParam.setOriginalConfigs(configs);
assignParam.setCpu(configs.getLong("cpu"));
assignParam.setMemory(configs.getBigDecimal("memory").longValue());
assignParam.setDisk(configs.getLong("disk"));
assignParam.setTemplateDisk(configs.getLong("templateDisk"));
assignParam.setInstance(count);
assignParam.setUuid(UUID.randomUUID().toString());
assignParam.setPoolGroupId(param.getLocation().getPoolGroupId());
param.setAssignParam(assignParam);
}
if (CloudProvider.HUAWEI == provider){
String instanceChargeType = "PostPaid";
if (ChargeCommon.ChargeMode.PreCharge.equals(order.getChargeMode())){
@ -410,6 +426,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 +549,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,16 +576,16 @@ 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()){
if (address.isEmpty()) {
BocloudResult<List<Ip>> listBocloudResult = ipService.achievePoolIps(ipPoolId, count.longValue(), null);
List<String> ips = listBocloudResult.getData().stream().map(Ip::getIp).collect(Collectors.toList());
logger.info("打印分配到的ip:{}",JSON.toJSONString(ips));
logger.info("打印分配到的ip:{}", JSON.toJSONString(ips));
address = JSONObject.parseArray(JSON.toJSONString(ips));
jsonObject.put("address",address);
jsonObject.put("address", address);
}
logger.info("打印address:{}",JSON.toJSONString(address));
logger.info("打印address:{}", JSON.toJSONString(address));
}
for (int i = 0; i < count; i++) {
JSONObject newObj = JSONObject.parseObject(configs.toJSONString());
@ -550,7 +607,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 +660,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 +757,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);

View File

@ -16,6 +16,7 @@ import com.bocloud.cmp.model.sangfor.SangforVsModel;
import com.bocloud.common.enums.ResourceCatalog;
import com.bocloud.common.model.*;
import com.bocloud.common.utils.*;
import com.bocloud.entity.bean.GenericEntity;
import com.bocloud.ims.entity.common.Dictionary;
import com.bocloud.ims.entity.resource.*;
import com.bocloud.ims.interfaces.resource.ServerService;
@ -163,8 +164,18 @@ public class ServerServiceImpl implements ServerService {
Double memoryCapacity, memUsed;
ServerConfig config;
Map<String, String> allAzUuidNameMap = sangforAzService.getAllAzUuidNameMap();
Map<Long, String> netMap = new HashMap<>();
if (null != vendor && "CLOUDTOWER".equals(vendor.getType())) {
List<Long> collect = list.stream().map(Server::getId).collect(Collectors.toList());
List<NetworkCard> networkCardList = networkCardRepository.queryProxy().col(NetworkCard::getHostId).in(collect)
.col(NetworkCard::getCategory).eq("PM")
.col(GenericEntity::getDeleted).eq(false).list();
netMap = networkCardList.stream().collect(Collectors.toMap(NetworkCard::getHostId, NetworkCard::getInstanceId, (existingValue, newValue) -> newValue));
}
for (Server server : list) {
if (null != vendor && "CLOUDTOWER".equals(vendor.getType())) {
server.setNicUuid(netMap.get(server.getId()));
}
azUuid = server.getAzUuid();
if (StringUtils.isNotEmpty(azUuid)) {
azName = allAzUuidNameMap.get(azUuid);
@ -229,6 +240,81 @@ public class ServerServiceImpl implements ServerService {
}
}
private void getServerList(int rows, List<Param> params, CloudVendor vendor, List<Server> list) throws Exception {
String azUuid, azName, ratioDesc;
Long cpuUsed, cpuHz;
Double memoryCapacity, memUsed;
ServerConfig config;
Map<String, String> allAzUuidNameMap = sangforAzService.getAllAzUuidNameMap();
Map<Long, String> netMap = new HashMap<>();
if (null != vendor && "CLOUDTOWER".equals(vendor.getType())) {
List<Long> collect = list.stream().map(Server::getId).collect(Collectors.toList());
List<NetworkCard> networkCardList = networkCardRepository.queryProxy().col(NetworkCard::getHostId).in(collect)
.col(NetworkCard::getCategory).eq("PM")
.col(GenericEntity::getDeleted).eq(false).list();
netMap = networkCardList.stream().collect(Collectors.toMap(NetworkCard::getHostId, NetworkCard::getInstanceId, (existingValue, newValue) -> newValue));
}
for (Server server : list) {
if (null != vendor && "CLOUDTOWER".equals(vendor.getType())) {
server.setNicUuid(netMap.get(server.getId()));
}
azUuid = server.getAzUuid();
if (StringUtils.isNotEmpty(azUuid)) {
azName = allAzUuidNameMap.get(azUuid);
if (StringUtils.isNotEmpty(azName)) {
server.setAzName(azName);
}
}
List<NetworkCard> networkCards = networkCardRepository.listByHostIdAndSwitcherAvailable(server.getId(), true);
server.setNetcards(networkCards);
params.clear();
params.add(new Param(MapTools.simpleMap("hostId", server.getId()), Sign.EQ));
int vmNum = cloudServerRepository.count(params, 0L);
params.add(new Param(MapTools.simpleMap("isTemplate", 1), Sign.EQ));
int templateNum = cloudServerRepository.count(params, 0L);
server.setVmNum(vmNum - templateNum);
server.setTemplateNum(templateNum);
if (!StringUtils.isEmpty(server.getResourceGroup())) {
Dictionary dictionary = dictionaryRepository.query(server.getResourceGroup(), "RESOURCE_GROUP");
if (null != dictionary) {
server.setResourceGroupName(dictionary.getName());
}
}
// 设置这个物理机的资源池
if (ServerAssetCategory.X86_SERVER.name().equals(server.getAssetCategory())) {
// 这是一个x86物理机
server.setGroupName(poolGroupRepository.getGroupNameByResourceTarget(server.getId(),
ResourceCategory.Computer.name(), ResourceCatalog.PHYSICAL.name()));
}
Optional.ofNullable(this.serverConfigRepository.getBySid(server.getId()))
.ifPresent(server::setConfig);
config = server.getConfig();
Optional.ofNullable(server.getRole()).ifPresent(role -> {
server.setRoles(new ArrayList<>(Arrays.asList(role.split(","))));
server.getRoles().remove("nfs_gateway");
});
// 深信服6.8宿主机下拉框增加CPU和内存利用率(非实时数据,以上次同步时候的数据计算)
if ("6.8".equalsIgnoreCase(vendor.getVersion()) && CloudProvider.SANGFOR.name().equals(vendor.getType()) && rows == 9999) {
ratioDesc = "(CPU" + new BigDecimal(server.getCpuRatio()).multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP).toString() + "%" + "-内存" + new BigDecimal(server.getMemRatio()).multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP).toString() + "%)";
server.setName(server.getName() + ratioDesc);
}
// vmware宿主机下拉框增加CPU和内存利用率(非实时数据,以上次同步时候的数据计算)
if (CloudProvider.VMWARE.name().equals(vendor.getType()) && rows >= 9999 && config != null) {
cpuUsed = (config.getCpuUsed() != null ? config.getCpuUsed() : 0L);
cpuHz = (config.getCpuHz() != null ? config.getCpuHz() : 0L);
memUsed = (config.getMemUsed() != null ? config.getMemUsed() : 0D);
memoryCapacity = (config.getMemoryCapacity() != null ? config.getMemoryCapacity() : 0D);
if (cpuHz > 0L && memoryCapacity > 0D) {
ratioDesc = "(CPU" + new BigDecimal(cpuUsed * 1.0D / cpuHz).multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP).toString() + "%" + "-内存" + new BigDecimal(memUsed / memoryCapacity).multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP).toString() + "%)";
server.setName(server.getName() + ratioDesc);
}
}
}
}
@Override
public BocloudResult<String> modify(String params, RequestContext context) {
return new BocloudResult(false, ServerService.class.getSimpleName() + "的modify方法未实现");

View File

@ -1,8 +1,15 @@
package com.bocloud.ims.service.rpc;
import com.alibaba.fastjson.JSON;
import com.bocloud.entity.bean.GenericEntity;
import com.bocloud.ims.entity.resource.CloudVendor;
import com.bocloud.ims.entity.resource.Ip;
import com.bocloud.ims.entity.resource.Server;
import com.bocloud.ims.entity.resource.ServerConfig;
import com.bocloud.ims.repository.resource.CloudVendorRepository;
import com.bocloud.ims.repository.resource.IpRepository;
import com.bocloud.ims.repository.resource.ServerConfigRepository;
import com.bocloud.ims.repository.resource.ServerRepository;
import com.bocloud.rpc.interfaces.ims.ImsRpcService;
import com.bocloud.service.lock.BocloudACLock;
import com.bocloud.service.lock.LockFactory;
@ -11,9 +18,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@Slf4j
@Service
@ -23,6 +30,12 @@ public class ImsRpcServiceImpl implements ImsRpcService {
@Autowired
IpRepository ipRepository;
@Autowired
private ServerRepository serverRepository;
@Autowired
private CloudVendorRepository cloudVendorRepositoryl;
@Autowired
private ServerConfigRepository serverConfigRepository;
@Override
public void preemptOrFreeIp(List<String> ipsToPreempt, List<String> ipsToFree) {
@ -54,4 +67,32 @@ public class ImsRpcServiceImpl implements ImsRpcService {
log.error("Get error message", e);
}
}
@Override
public List<Server> getServerByName(List<String> serverNameList, Long vendorId) {
return serverRepository.queryProxy().col(GenericEntity::getName).in(serverNameList)
.col(Server::getVendorId).eq(vendorId)
.col(GenericEntity::getDeleted).eq(false).list();
}
@Override
public List<Server> getServerAll(Set<Long> vendorIds) throws Exception {
// 获取云平台
List<CloudVendor> vendorList = cloudVendorRepositoryl.queryProxy().col(GenericEntity::getDeleted).eq(0)
.col(CloudVendor::getId).in(vendorIds)
.list();
List<Server> servers = new ArrayList<>();
// 获取serverConfig
List<ServerConfig> serverConfigList = serverConfigRepository.queryProxy().list();
Map<Long, ServerConfig> serverConfigMap = serverConfigList.stream()
.collect(Collectors.toMap(ServerConfig::getServerId, serverConfig -> serverConfig));
for (CloudVendor cloudVendor : vendorList) {
List<Server> list = this.serverRepository.list(1, 100000, null, null, null, cloudVendor.getType(), null, null);
for (Server server : list) {
server.setConfig(serverConfigMap.get(server.getId()));
}
servers.addAll(list);
}
return servers;
}
}

View File

@ -2502,6 +2502,7 @@ public class CmpStatsServiceImpl implements CmpStatsService {
if("VMWARE".equalsIgnoreCase(vendor)) {
diskType = "PB";
}
diskTotal = new BigDecimal(diskTotal).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
diskMap.put("name", "磁盘");
diskMap.put("value", disk);
diskMap.put("total", diskTotal + diskType);

View File

@ -706,6 +706,7 @@ public class VmwareTransporter implements ResourceTransporter {
for (CloudServer cloudServer : cloudServers) {
CloudServer server = cloudServerRepository.getByInstanceId(cloudServer.getInstanceId());
VmResourcePool vmResourcePool = resourcePoolRepository.queryByPoolVal(cloudServer.getResPoolVal(), vdcId);
log.info("虚拟机信息:" + JSONObject.toJSONString(server));
if (null != vmResourcePool && null != server) {
server.setResPoolId(vmResourcePool.getId());
cloudServerRepository.update(server);

View File

@ -78,6 +78,7 @@ import com.bocloud.ims.service.internal.worker.LvmService;
import com.bocloud.ims.service.model.ProcessResult;
import com.bocloud.ims.service.resource.fusionsphere.utils.FusionSphereResourceUtils;
import com.bocloud.ims.service.task.ResourceTaskNotice;
import com.bocloud.ims.service.transporter.vendor.CloudTowerTransporter;
import com.bocloud.ims.service.transporter.vendor.H3cTransporter;
import com.bocloud.ims.service.transporter.vendor.PowervcTransporter;
import com.bocloud.ims.service.transporter.vendor.SmartxTransporter;
@ -327,6 +328,8 @@ public class ServerOperationHelper {
private ResourceOperatorFactory resourceOperatorFactory;
@Autowired
private ProviderContextManager providerContextManager;
@Autowired
private CloudTowerTransporter cloudTowerTransporter;
/**
* builder
@ -482,6 +485,12 @@ public class ServerOperationHelper {
process = new SangforBuilder(context, vendor, serverDriver,cloudServerRepository,volumeRepository, dataStoreRepository,
networkRepository, cosInternalService, serverRepository, shtermService);
break;
case CLOUDTOWER:
process = new CloudTowerServerBuilder(cloudVendorRepository, serverRepository, cloudServerRepository,
volumeRepository, volumeTemplateRepository, imageRepository, switcherRepository,
networkRepository, subnetRepository, serverVolumeRepository, serverImageRepository,
serverDriver, volumeDriver, serverTemplateDriver, cloudTowerTransporter, context, clusterRepository, networkCardRepository);
break;
default:
//默认走acd的ServerBuilder
process = new ResourceOperatorServerBuilder(resourceOperatorFactory, vendor, providerContextManager);
@ -1127,6 +1136,13 @@ public class ServerOperationHelper {
return new BocloudResult<>(false, modelResult.getMessage());
}
break;
case CLOUDTOWER:
inputObject = JSONObject.parseObject(JSONObject.toJSONString(params));
modelResult = process.prepare(inputObject);
if (modelResult.isFailed()) {
return new BocloudResult<>(false, modelResult.getMessage());
}
break;
case VMWARE:
// 路由器id
Long vpcId = params.getVpcId();

View File

@ -406,6 +406,7 @@ public class SyncVmwareUtils {
}
log.info("更新旧虚拟机:{}", oldServer.getId());
log.info("虚拟机信息:" + JSONObject.toJSONString(oldServer));
cloudServerRepository.update(oldServer);
log.info("更新旧虚拟机完成:{}", oldServer.getId());
Long serverId = oldServer.getId();
@ -694,6 +695,7 @@ public class SyncVmwareUtils {
cloudServer.setResourceId(IDFactory.instance().uuid());
cloudServer.setRecycle(false);
cloudServer.setCatalog(Catalog.Manager);
log.info("虚拟机信息:" + JSONObject.toJSONString(cloudServer));
cloudServerRepository.save(cloudServer);
Long serverId = cloudServer.getId();
if (cloudServer.getIsTemplate()) {