diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/controller/FlavorController.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/controller/FlavorController.java index 25e9ce77..f2024f21 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/controller/FlavorController.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/controller/FlavorController.java @@ -116,6 +116,15 @@ public class FlavorController { return flavorService.remove(id, context); } + @Operation(tags = {"CMC", "CSC"}, summary = "查询物理机规格") + @DeleteMapping("/listPhysical") + public GeneralResult listPhysical(@RequestParam(value = "vendorId") Long vendorId, + @RequestParam(value = "regionId") String regionId, + @RequestParam(value = "zoneId") String zoneId, + @Value(Common.REQ_CONTEXT) RequestContext context) { + return flavorService.listPhysical(vendorId, regionId, zoneId, context); + } + /** * 批量删除云主机规格 * diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/controller/PhysicalServerController.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/controller/PhysicalServerController.java new file mode 100644 index 00000000..6189c85e --- /dev/null +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/controller/PhysicalServerController.java @@ -0,0 +1,75 @@ +package com.bocloud.ctstack.plugin.controller; + +import com.bocloud.cmp.entity.PhysicalServer; +import com.bocloud.ctstack.plugin.service.PhysicalServerService; +import com.megatron.common.model.GeneralResult; +import com.megatron.common.model.GridBean; +import com.megatron.common.model.Pager; +import com.megatron.common.model.RequestContext; +import com.megatron.common.utils.Common; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author zhangdi + * @since 2018/7/2 + */ +@RestController +@RequestMapping("/v1/physical/servers") +@Tag(name = "命名规则") +public class PhysicalServerController { + + @Autowired + private PhysicalServerService physicalServerService; + + + @Operation(tags = {"CMC", "CSC"}, summary = "获取命名规则列表") + @GetMapping + public GeneralResult> list(Pager pager, + @Value(Common.REQ_CONTEXT) RequestContext context) { + return physicalServerService.list(pager, context); + } + + + @Operation(tags = {"CMC", "CSC"}, summary = "添加标签") + @PostMapping + public GeneralResult create(@RequestBody PhysicalServer physicalServer, + @Value(Common.REQ_CONTEXT) RequestContext context) { + return physicalServerService.create(physicalServer, context); + } + + + @Operation(tags = {"CMC", "CSC"}, summary = "修改标签") + @PutMapping("/{id}") + public GeneralResult modify(@PathVariable(value = Common.ID) Long id, + @RequestBody PhysicalServer physicalServer, + @Value(Common.REQ_CONTEXT) RequestContext context) { + physicalServer.setId(id); + return physicalServerService.modify(physicalServer, context); + } + + @Operation(tags = {"CMC", "CSC"}, summary = "删除标签") + @DeleteMapping("/{id}") + public GeneralResult remove(@PathVariable(value = Common.ID) Long id, + @Value(Common.REQ_CONTEXT) RequestContext context) { + return physicalServerService.remove(id, context); + } + + + @Operation(tags = {"CMC", "CSC"}, summary = "查看标签详情") + @GetMapping("/{id}") + public GeneralResult detail(@PathVariable(value = Common.ID) Long id) { + return physicalServerService.detail(id); + } + +} \ No newline at end of file diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/HostModel.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/HostModel.java index edf5c11a..8879d7d8 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/HostModel.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/HostModel.java @@ -90,6 +90,8 @@ public class HostModel { private Long hddTotalSizeByte; private Long ssdTotalSizeByte; + private Boolean isHost; + /** * @param name * @param uuid diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/ImageModel.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/ImageModel.java index 15c703ae..767e8aa4 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/ImageModel.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/ImageModel.java @@ -75,4 +75,5 @@ public class ImageModel { // hcso private String wholeImageType; private String backupUuid; + private Boolean isPhysical; } diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/PhysicalServerModel.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/PhysicalServerModel.java new file mode 100644 index 00000000..aaeba42f --- /dev/null +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/PhysicalServerModel.java @@ -0,0 +1,94 @@ +package com.bocloud.ctstack.plugin.domain.model; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class PhysicalServerModel { + + private Long id; + + private String regionId; + + private String zoneId; + + private Long vendorId; + + private String resourceId; + + private String instanceUuid; + + private String deviceUuid; + + private String deviceType; + + private String name; + + private String displayName; + + private String remark; + + private String systemVolumeRaidId; + + private String dataVolumeRaidId; + + private String imageUuid; + + private Long osType; + + private String osTypeName; + + private String vpcUuid; + + private String subnetUuid; + + private String privateIp; + + private String publicIp; + + private String ebmState; + + private String flavor; + + private String interfaces; + + private String raidDetail; + + private String attachedVolumes; + + private String deviceDetail; + + private Boolean freezing; + + private String localId;// cloudtower监控需要用到 + + private Boolean expired; + + private String createTime; + + private String updatedTime; + + private String deleteTime; + + private String expiredTime; + + private Boolean onDemand; + + private Date gmtCreate; + + private Date gmtModify; + + private Long creatorId; + + private Long tenantId; + + private Long projectId; + + private Boolean isDeleted; + +} diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/TianyiSyncModel.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/TianyiSyncModel.java index c216c52a..4f5988e0 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/TianyiSyncModel.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/domain/model/TianyiSyncModel.java @@ -32,6 +32,7 @@ public class TianyiSyncModel { private List networkCardModels; private List clusterModels; private List hostModels; + private List physicalModels; private ResourcePoolModel resourcePoolModel; private List rdsModels; private List contarinerClusterModels; diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiFlavorProvider.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiFlavorProvider.java index 280016c6..9d743587 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiFlavorProvider.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiFlavorProvider.java @@ -75,4 +75,25 @@ public class TianyiFlavorProvider extends TianyiServerProvider { return new GeneralResult(false, "查询规格列表失败", e.getMessage()); } } + + public GeneralResult listPhysical(String regionId, String azName) { + try { + String apiUrl = "/v4/ebm/device-type-list"; + JSONObject body = new JSONObject(); + body.put("regionID", this.getRegionId()); + body.put("azName", azName); + + Result result = doGet(apiUrl, null, body); + JSONObject returnObj = checkResult(result, "查询物理机规格列表"); + + List results = JSONArray.parseArray(returnObj.getString("results"), JSONObject.class); + if (ListTool.isEmpty(results)) { + return new GeneralResult(true, results, "物理机规格列表为空"); + } + return new GeneralResult(true, results, "查询物理机规格列表成功"); + } catch (Exception e) { + log.error("查询物理机规格列表失败 : " + e); + return new GeneralResult(false, "查询物理机规格列表失败", e.getMessage()); + } + } } diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiLocationProvider.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiLocationProvider.java index 25b239b8..7cf14d3e 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiLocationProvider.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/common/TianyiLocationProvider.java @@ -8,6 +8,7 @@ import com.bocloud.ctstack.plugin.domain.model.database.ProjectModel; import com.bocloud.ctstack.plugin.domain.model.database.RdsModel; import com.bocloud.ctstack.plugin.provider.TianyiProvider; import com.bocloud.ctstack.plugin.provider.compute.TianyiImageProvider; +import com.bocloud.ctstack.plugin.provider.compute.TianyiPhysicalProvider; import com.bocloud.ctstack.plugin.provider.compute.TianyiServerProvider; import com.bocloud.ctstack.plugin.provider.container.TianYiContainerClusterProvider; import com.bocloud.ctstack.plugin.provider.database.TianyiRdsProvider; @@ -152,6 +153,7 @@ public class TianyiLocationProvider extends TianyiProvider { hostModel.setName(object.getString("hostName")); hostModel.setHostName(object.getString("hostName")); hostModel.setHostIp(object.getString("ip")); + hostModel.setIsHost(true); String cpuInfo = object.getString("cpuInfo"); if (!StringUtils.isEmpty(cpuInfo)) { @@ -216,6 +218,13 @@ public class TianyiLocationProvider extends TianyiProvider { if(clusterResult.isSuccess()){ syncModel.setHostModels(clusterResult.getData()); } + log.info("获取物理机信息..."); + TianyiPhysicalProvider physicalProvider = new TianyiPhysicalProvider(this.getButler()); + GeneralResult> physicalResult = physicalProvider.list(); + log.info("同步物理机结果:{}", physicalResult.isSuccess()); + if(physicalResult.isSuccess()){ + syncModel.setPhysicalModels(physicalResult.getData()); + } // 同步vpc log.info("获取vpc信息..."); TianyiVpcProvider tianyiVpcProvider = new TianyiVpcProvider(this.getButler()); diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/compute/TianyiPhysicalProvider.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/compute/TianyiPhysicalProvider.java new file mode 100644 index 00000000..8bad275b --- /dev/null +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/compute/TianyiPhysicalProvider.java @@ -0,0 +1,119 @@ +package com.bocloud.ctstack.plugin.provider.compute; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.domain.Butler; +import com.bocloud.ctstack.plugin.domain.model.PhysicalServerModel; +import com.bocloud.ctstack.plugin.provider.TianyiProvider; +import com.bocloud.ctstack.plugin.provider.tianyiconvertor.BeanConvertor; +import com.bocloud.ctstack.plugin.provider.tianyiconvertor.PhyscicalConvertor; +import com.megatron.common.model.GeneralResult; +import com.megatron.common.model.Result; +import com.megatron.common.utils.ListTool; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.util.CollectionUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author yuemian + * @create 2024-09-02 + * @Description: 物理机相关接口 + */ + +@Slf4j +public class TianyiPhysicalProvider extends TianyiProvider { + + public TianyiPhysicalProvider(Butler butler) { + super(butler); + } + + private BeanConvertor physcicalConvertor = new PhyscicalConvertor(); + + + public GeneralResult> list() { + try { + List physicalModels = new ArrayList<>(); + List zoneList = this.listZones(this.getRegionId()); + if (!CollectionUtils.isEmpty(zoneList)) { + List results = new ArrayList<>(); + for (JSONObject zone : zoneList) { + String apiUrl = "/v4/ebm/list"; + JSONObject body = new JSONObject(); + body.put("regionID", this.getRegionId()); + body.put("azName", zone.getString("name")); + Result result = doGet(apiUrl, null, body); + JSONObject returnObj = checkResult(result, "查询物理机列表"); + results.addAll(JSONArray.parseArray(returnObj.getString("results"), JSONObject.class)); + } + if (ListTool.isEmpty(results)) { + return new GeneralResult(true, results, "物理机列表为空"); + } + for (JSONObject model : results) { + physicalModels.add(physcicalConvertor.convertModel(model)); + } + } + return new GeneralResult(true, physicalModels, "查询宿主机列表成功"); + } catch (Exception e) { + log.error("查询宿主机列表失败 :", e); + return new GeneralResult(false, "查询宿主机列表失败" + e.getMessage()); + } + } + + public List listZones(String regionId) { + try { + Thread.sleep(1500); + String apiUrl = "/v4/region/get-zones"; + JSONObject body = new JSONObject(); + body.put("regionID", regionId); + Result result = doGet(apiUrl, null, body); + JSONObject returnObj = checkResult(result, "查询可用区列表"); + + List jsonObjects = JSONArray.parseArray(returnObj.getString("zoneList"), JSONObject.class); + return jsonObjects; + } catch (Exception e) { + log.error("查询资源池列表失败 :", e); + return null; + } + } + + public GeneralResult modify(PhysicalServerModel model) { + try { + String apiUrl = "/v4/ebm/update"; + JSONObject headers = new JSONObject(); + headers.put("regionId", this.getRegionId()); + headers.put("instanceUUID", model.getInstanceUuid()); + if (StringUtils.isNotBlank(model.getRemark())) { + headers.put("description", model.getRemark()); + } + if (StringUtils.isNotBlank(model.getDisplayName())) { + headers.put("displayName", model.getDisplayName()); + } + + Result result = doPost(apiUrl, headers); + checkResult(result, "修改物理主机"); + return new GeneralResult(true, "修改物理机成功"); + } catch (Exception e) { + log.error("修改物理机失败 : " + e); + return new GeneralResult(false, "修改物理机失败", e.getMessage()); + } + } + + public GeneralResult remove(PhysicalServerModel model) { + try { + String apiUrl = "/v4/ebm/delete"; + JSONObject jsonObject = new JSONObject(); + jsonObject.put("regionID", this.getRegionId()); + jsonObject.put("azName", model.getZoneId()); + jsonObject.put("instanceUUID", model.getInstanceUuid()); + Result result = doPost(apiUrl, jsonObject); + checkResultArray(result, "删除物理机"); + return new GeneralResult(true, "删除物理机成功"); + } catch (Exception e) { + log.error("删除物理机失败 : " + e.getMessage(), e); + return new GeneralResult(false, "删除物理机失败", e.getMessage()); + } + } +} diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/tianyiconvertor/PhyscicalConvertor.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/tianyiconvertor/PhyscicalConvertor.java new file mode 100644 index 00000000..0bcdbd0c --- /dev/null +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/provider/tianyiconvertor/PhyscicalConvertor.java @@ -0,0 +1,73 @@ +package com.bocloud.ctstack.plugin.provider.tianyiconvertor; + + +import com.alibaba.fastjson.JSONObject; +import com.bocloud.ctstack.plugin.domain.model.PhysicalServerModel; + +/** + * @Package: com.bocloud.cmp.provider.tianyiconvertor + * @ClassName: VpcConvertor1 + * @Author: 胡文涛 + * @CreateTime: 2020/9/30 10:25 + * @Description: + */ +public class PhyscicalConvertor implements BeanConvertor { + + + + @Override + public PhysicalServerModel convertModel(JSONObject info) { + PhysicalServerModel model = new PhysicalServerModel(); + if (null != info) { + model.setRegionId(info.getString("region")); + model.setZoneId(info.getString("azName")); + model.setName(info.getString("name")); + model.setResourceId(info.getString("resourceId")); + model.setInstanceUuid(info.getString("instanceUUID")); + model.setDeviceUuid(info.getString("deviceUuid")); + model.setDeviceType(info.getString("deviceType")); + model.setName(info.getString("name")); + model.setRemark(info.getString("description")); + model.setSystemVolumeRaidId(info.getString("systemVolumeRaidID")); + model.setDataVolumeRaidId(info.getString("dataVolumeRaidID")); + model.setImageUuid(info.getString("imageID")); + model.setOsType(info.getLong("osType")); + model.setOsTypeName(info.getString("osTypeName")); + model.setVpcUuid(info.getString("vpcID")); + model.setSubnetUuid(info.getString("subnetID")); + model.setPrivateIp(info.getString("privateIp")); + model.setPublicIp(info.getString("publicIp")); + model.setEbmState(info.getString("ebmState")); + model.setDisplayName(info.getString("displayName")); + if (info.getJSONObject("flavor") != null) { + model.setFlavor(info.getJSONObject("flavor").toJSONString()); + } + if (info.getJSONArray("interfaces") != null) { + model.setInterfaces(info.getJSONArray("interfaces").toJSONString()); + } + if (info.getJSONObject("raidDetail") != null) { + model.setRaidDetail(info.getJSONObject("raidDetail").toJSONString()); + } + if (info.getJSONArray("attachedVolumes") != null) { + model.setAttachedVolumes(info.getJSONArray("attachedVolumes").toJSONString()); + } + if (info.getJSONObject("deviceDetail") != null) { + model.setDeviceDetail(info.getJSONObject("deviceDetail").toJSONString()); + } + model.setFreezing(info.getBoolean("freezing")); + model.setExpired(info.getBoolean("expired")); + model.setCreateTime(info.getString("createdTime")); + model.setUpdatedTime(info.getString("updatedTime")); + model.setDeleteTime(info.getString("deleteTime")); + model.setExpiredTime(info.getString("expiredTime")); + model.setOnDemand(info.getBoolean("onDemand")); + model.setIsDeleted(false); + model.setCreatorId(1L); + model.setTenantId(0L); + model.setProjectId(0L); + } + return model; + } + + +} diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/repository/PhysicalServerRepository.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/repository/PhysicalServerRepository.java new file mode 100644 index 00000000..160ba511 --- /dev/null +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/repository/PhysicalServerRepository.java @@ -0,0 +1,73 @@ +package com.bocloud.ctstack.plugin.repository; + +import com.bocloud.cmp.entity.PhysicalServer; +import com.megatron.common.model.Pager; +import com.megatron.common.model.Param; +import com.megatron.common.utils.Common; +import com.megatron.common.utils.MapTools; +import com.megatron.database.core.intf.impl.BasicGenericDao; +import com.megatron.framework.core.CurrentService; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 物理服务器数据访问 + * + * @author wangyu + * @version 1.0 + * @since 2020年5月15日 + */ +@Repository("serverRepository") +public class PhysicalServerRepository extends BasicGenericDao { + + + public PhysicalServerRepository(JdbcTemplate jdbcTemplate, NamedParameterJdbcTemplate npJdbcTemplate, CurrentService service) { + super(jdbcTemplate, npJdbcTemplate, service); + } + + public List listByVendor(Long vendorId) { + String sql = "select a.* from physical_server a where a.is_deleted = 0"; + Map params = new HashMap<>(8); + if (null != vendorId) { + sql += " and a.vendor_id = :vendorId"; + params.put(Common.VENDORID, vendorId); + } + return this.list(PhysicalServer.class, sql, params); + } + + public boolean removeByVendor(Long vendorId, Long userId) { + String sql = "update physical_server set is_deleted = true , gmt_modify = :gmtModify where is_deleted = 0 and vendor_id = :vendorId"; + Map params = MapTools.simpleMap(Common.VENDORID, vendorId); + params.put("gmtModify", new Date()); + return this.execute(sql, params) > 0; + } + + public boolean remove(Long id, Long userId) { + String sql = "update physical_server set is_deleted = true,gmt_modify = :gmtModify, mender_id = :userId where is_deleted = 0 and id = :id"; + Map params = MapTools.simpleMap("id", id); + params.put("gmtModify", new Date()); + params.put("userId", userId); + return this.execute(sql, params) > 0; + } + + public int count(List params) throws Exception { + String sql = "select count(1) from physical_server where 1 = 1 "; + sql = this.getQueryBuilder().build(sql, params, new HashMap<>(8), ""); + Map param = this.getQueryBuilder().getParam(params); + return this.countQuery(sql, param).intValue(); + } + + public List list(int page, int rows, List params, Map sorter) throws Exception { + String sql = "select a.* from physical_server a where 1 = 1 "; + sql = this.getQueryBuilder().build(sql, new Pager(page, rows, params, sorter), "a"); + Map param = this.getQueryBuilder().getParam(params); + return this.list(PhysicalServer.class, sql, param); + } + +} diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/FlavorService.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/FlavorService.java index 3798ac5f..8c9006b2 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/FlavorService.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/FlavorService.java @@ -56,6 +56,8 @@ public interface FlavorService { */ GeneralResult remove(Long id, RequestContext context); + GeneralResult listPhysical(Long vendorId, String regionId, String zoneId, RequestContext context); + /** * 修改配置 * diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/PhysicalServerService.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/PhysicalServerService.java new file mode 100644 index 00000000..b9fbea75 --- /dev/null +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/PhysicalServerService.java @@ -0,0 +1,26 @@ +package com.bocloud.ctstack.plugin.service; + +import com.bocloud.cmp.entity.PhysicalServer; +import com.megatron.common.model.GeneralResult; +import com.megatron.common.model.GridBean; +import com.megatron.common.model.Pager; +import com.megatron.common.model.RequestContext; + +public interface PhysicalServerService { + + + GeneralResult> list(Pager pager, RequestContext context); + + + GeneralResult detail(Long id); + + GeneralResult create(PhysicalServer physicalServer, RequestContext context); + + + GeneralResult modify(PhysicalServer physicalServer, RequestContext context); + + GeneralResult remove(Long id, RequestContext context); + + + +} diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/FlavorServiceImpl.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/FlavorServiceImpl.java index 4297e871..82f439e2 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/FlavorServiceImpl.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/FlavorServiceImpl.java @@ -7,6 +7,7 @@ import com.bocloud.cmp.util.ResourceEventPublisher; import com.bocloud.ctstack.plugin.config.ButlerConfig; import com.bocloud.ctstack.plugin.entity.Flavor; import com.bocloud.ctstack.plugin.entity.Region; +import com.bocloud.ctstack.plugin.provider.common.TianyiFlavorProvider; import com.bocloud.ctstack.plugin.repository.CloudServerRepository; import com.bocloud.ctstack.plugin.repository.FlavorExtraSpecsRepository; import com.bocloud.ctstack.plugin.repository.FlavorRepository; @@ -15,8 +16,17 @@ import com.bocloud.ctstack.plugin.service.FlavorService; import com.bocloud.ctstack.plugin.util.ExcelExporter; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.megatron.common.model.*; -import com.megatron.common.utils.*; +import com.megatron.common.model.GeneralResult; +import com.megatron.common.model.GridBean; +import com.megatron.common.model.OperateResult; +import com.megatron.common.model.Pager; +import com.megatron.common.model.Param; +import com.megatron.common.model.RequestContext; +import com.megatron.common.utils.Common; +import com.megatron.common.utils.DateTools; +import com.megatron.common.utils.GridHelper; +import com.megatron.common.utils.ListTool; +import com.megatron.common.utils.MapTools; import com.megatron.framework.lock.LockFactory; import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; @@ -28,7 +38,12 @@ import org.springframework.util.ObjectUtils; import java.io.IOException; import java.io.OutputStream; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; /** @@ -142,6 +157,21 @@ public class FlavorServiceImpl implements FlavorService { } + @Override + public GeneralResult listPhysical(Long vendorId, String regionId, String zoneId, RequestContext context) { + try { + CloudVendor vendor = cloudVendorRepository.query(vendorId); + if (vendor == null) { + return GeneralResult.FAILED("云平台不存在"); + } + TianyiFlavorProvider flavorProvider = new TianyiFlavorProvider(butlerConfig.regionButler(vendor.getUuid(), regionId)); + return flavorProvider.listPhysical(regionId, zoneId); + } catch (Exception e) { + log.error("查询物理机规格失败"+ e.getMessage(), e); + return GeneralResult.FAILED("查询物理机规格失败"+ e.getMessage()); + } + } + @Override public GeneralResult create(Flavor flavor, RequestContext context) { return new GeneralResult<>(false, "暂不支持!"); @@ -152,6 +182,7 @@ public class FlavorServiceImpl implements FlavorService { return new GeneralResult<>(false, "暂不支持!"); } + @Override public GeneralResult modify(Flavor flavorParam, RequestContext context) { return new GeneralResult<>(false, "暂不支持!"); diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/PhysicalServerServiceImpl.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/PhysicalServerServiceImpl.java new file mode 100644 index 00000000..faa8e3d1 --- /dev/null +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/PhysicalServerServiceImpl.java @@ -0,0 +1,156 @@ +package com.bocloud.ctstack.plugin.service.impl; + +import com.bocloud.cmp.entity.CloudVendor; +import com.bocloud.cmp.entity.PhysicalServer; +import com.bocloud.cmp.repository.CloudVendorRepository; +import com.bocloud.ctstack.plugin.repository.PhysicalServerRepository; +import com.bocloud.ctstack.plugin.config.ButlerConfig; +import com.bocloud.ctstack.plugin.domain.model.PhysicalServerModel; +import com.bocloud.ctstack.plugin.entity.Label; +import com.bocloud.ctstack.plugin.provider.compute.TianyiPhysicalProvider; +import com.bocloud.ctstack.plugin.repository.ResourceEventRepository; +import com.bocloud.ctstack.plugin.repository.VolumeRepository; +import com.bocloud.ctstack.plugin.repository.VpcRepository; +import com.bocloud.ctstack.plugin.service.PhysicalServerService; +import com.google.common.collect.Maps; +import com.megatron.common.model.GeneralResult; +import com.megatron.common.model.GridBean; +import com.megatron.common.model.Pager; +import com.megatron.common.model.Param; +import com.megatron.common.model.RequestContext; +import com.megatron.common.utils.GridHelper; +import com.megatron.framework.lock.AutoCloseLock; +import com.megatron.framework.lock.LockFactory; +import lombok.extern.slf4j.Slf4j; +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.Map; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service("physicalServerService") +public class PhysicalServerServiceImpl implements PhysicalServerService { + + @Autowired + private LockFactory lockFactory; + @Autowired + private ResourceEventRepository resourceEventRepository; + @Autowired + private CloudVendorRepository cloudVendorRepository; + @Autowired + private VpcRepository vpcRepository; + @Autowired + private VolumeRepository volumeRepository; + @Autowired + private PhysicalServerRepository physicalServerRepository; + @Autowired + private ButlerConfig butlerConfig; + + @Override + public GeneralResult> list(Pager pager, RequestContext context) { + List list = null; + int total = 0; + GridBean gridBean = null; + try { + List params = Optional.ofNullable(pager.getParams()).orElse(new ArrayList<>()); + Map sorter = Optional.ofNullable(pager.getSorter()).orElse(Maps.newHashMap()); + Boolean simple = Optional.ofNullable(pager.getSimple()).orElse(false); + Integer page = Optional.ofNullable(pager.getPage()).orElse(1); + Integer rows = Optional.ofNullable(pager.getRows()).orElse(10); + total = physicalServerRepository.count(params); + list = physicalServerRepository.list(page, rows, params, sorter); + gridBean = GridHelper.getBean(page, rows, total, list); + return new GeneralResult<>(true, gridBean, "查询成功"); + } catch (Exception e) { + log.error("list physical server failure:", e); + return new GeneralResult<>(false, "查询失败"); + } + } + + @Override + public GeneralResult detail(Long id) { + try { + PhysicalServer physicalServer = physicalServerRepository.get(PhysicalServer.class, id); + return new GeneralResult<>(true, physicalServer, "查询成功"); + } catch (Exception e) { + log.error("Get error message:", e); + return new GeneralResult<>(false, "查询失败"); + } + } + + @Override + public GeneralResult create(PhysicalServer physicalServer, RequestContext context) { + return null; + } + + @Override + public GeneralResult modify(PhysicalServer physicalServer, RequestContext context) { + String path = PhysicalServer.class.getSimpleName() + "_" + physicalServer.getId(); + try (AutoCloseLock lock = lockFactory.getACLock(path)) { + Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时"); + PhysicalServer oldServer = this.physicalServerRepository.get(PhysicalServer.class, physicalServer.getId()); + if (null == oldServer) { + log.warn("physical server does not exist!"); + return new GeneralResult<>(false, "数据不存在"); + } + CloudVendor vendor = cloudVendorRepository.query(oldServer.getVendorId()); + if (vendor == null) { + return GeneralResult.FAILED("云平台不存在"); + } + new Thread(() -> { + PhysicalServerModel model = new PhysicalServerModel(); + model.setInstanceUuid(oldServer.getInstanceUuid()); + model.setRegionId(oldServer.getRegionId()); + model.setZoneId(oldServer.getZoneId()); + model.setRemark(physicalServer.getRemark()); + TianyiPhysicalProvider physicalProvider = new TianyiPhysicalProvider(butlerConfig.regionButler(vendor.getUuid(), oldServer.getRegionId())); + GeneralResult result = physicalProvider.modify(model); + if (result.isSuccess()) { + oldServer.setRemark(physicalServer.getRemark()); + physicalServerRepository.update(oldServer); + } + }).start(); + return new GeneralResult<>(true, "修改任务已下发"); + } catch (Exception e) { + log.error("Modify label error:", e); + return new GeneralResult<>(false, "修改失败"); + } + } + + @Override + public GeneralResult remove(Long id, RequestContext context) { + String path = Label.class.getSimpleName() + "_" + id; + try (AutoCloseLock lock = lockFactory.getACLock(path)) { + Assert.isTrue(lock.acquire(10, TimeUnit.SECONDS), "请求超时"); + PhysicalServer oldServer = this.physicalServerRepository.get(PhysicalServer.class, id); + if (null == oldServer) { + log.warn("physical server does not exist!"); + return new GeneralResult<>(false, "数据不存在"); + } + CloudVendor vendor = cloudVendorRepository.query(oldServer.getVendorId()); + if (vendor == null) { + return GeneralResult.FAILED("云平台不存在"); + } + new Thread(() -> { + PhysicalServerModel model = new PhysicalServerModel(); + model.setInstanceUuid(oldServer.getInstanceUuid()); + model.setRegionId(oldServer.getRegionId()); + model.setZoneId(oldServer.getZoneId()); + TianyiPhysicalProvider physicalProvider = new TianyiPhysicalProvider(butlerConfig.regionButler(vendor.getUuid(), oldServer.getRegionId())); + GeneralResult result = physicalProvider.remove(model); + if (result.isSuccess()) { + physicalServerRepository.remove(id, context.getTarget()); + } + }).start(); + return new GeneralResult<>(true, "删除任务下发"); + } catch (Exception e) { + log.error("Remove physical server error:", e); + return new GeneralResult<>(false, "删除任务下发失败"); + } + } +} diff --git a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/TianyiTransporter.java b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/TianyiTransporter.java index 3230e772..02dc5680 100644 --- a/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/TianyiTransporter.java +++ b/bocloud.ctstack.plugin/src/main/java/com/bocloud/ctstack/plugin/service/impl/TianyiTransporter.java @@ -4,9 +4,11 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.bocloud.cmp.entity.CloudVendor; +import com.bocloud.cmp.entity.PhysicalServer; import com.bocloud.cmp.entity.Server; import com.bocloud.cmp.entity.ServerConfig; import com.bocloud.cmp.enums.ResourceCategory; +import com.bocloud.ctstack.plugin.repository.PhysicalServerRepository; import com.bocloud.cmp.repository.ServerRepository; import com.bocloud.ctstack.plugin.config.ButlerConfig; import com.bocloud.ctstack.plugin.domain.model.*; @@ -102,6 +104,8 @@ public class TianyiTransporter { private CtResourcePoolInfoRepository ctResourcePoolInfoRepository; @Autowired private CloudRdsRepository cloudRdsRepository; + @Autowired + private PhysicalServerRepository physicalServerRepository; public Result transport(CloudVendor vendor, Long operator) { @@ -173,6 +177,10 @@ public class TianyiTransporter { log.info("Starting sync host......"); this.syncHost(hostModels, vendor.getId(), userId); log.info("End sync host......"); + //同步物理机 + log.info("Starting sync physical server......"); + this.syncPhysicalServer(model.getPhysicalModels(), vendor.getId(), userId); + log.info("End sync physical server......"); // 同步vpc log.info("Starting sync vpc......"); this.syncVpc(model.getVpcModels(), vendor.getId(), userId, region); @@ -414,6 +422,45 @@ public class TianyiTransporter { } } + private void syncPhysicalServer(List physicalServerModels, Long vendorId, Long userId) { + if (ListTool.isEmpty(physicalServerModels)) { + List servers = physicalServerRepository.listByVendor(vendorId); + physicalServerRepository.removeByVendor(vendorId, userId); + return; + } + List physicalServers = physicalServerRepository.listByVendor(vendorId); + Map serverMap = Maps.newHashMap(); + for (PhysicalServer server : physicalServers) { + serverMap.put(server.getInstanceUuid(), server); + } + for (PhysicalServerModel physicalServerModel : physicalServerModels) { + PhysicalServer server = null; + if (serverMap.containsKey(physicalServerModel.getInstanceUuid())) { + server = serverMap.get(physicalServerModel.getInstanceUuid()); + if (server != null) { + BeanUtils.copyProperties(physicalServerModel, server, new String[]{"id", "tenantId", "creatorId", "projectId", "isDeleted", "gmtCreate"}); + physicalServerRepository.update(server); + serverMap.remove(server.getInstanceUuid()); + continue; + } + } + server = new PhysicalServer(); + BeanUtils.copyProperties(physicalServerModel, server); + server.setVendorId(vendorId); + server.setIsDeleted(false); + server.setGmtCreate(new Date()); + server.setGmtModify(new Date()); + server.setCreatorId(userId); + server.setTenantId(0L); + server.setProjectId(0L); + physicalServerRepository.save(server); + } + for (Map.Entry entry : serverMap.entrySet()) { + Long serverId = entry.getValue().getId(); + physicalServerRepository.remove(serverId, userId); + } + } + /** * @author Hu Wentao * @date 2020/10/29 10:31