diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c5d1c4e --- /dev/null +++ b/pom.xml @@ -0,0 +1,38 @@ + + + 4.0.0 + + com.bocloud + bocloud.bre + 5.5.0-RELEASE + + bocloud.tce.provider + + 5.5.0-RELEASE + + + + com.bocloud + bocloud.bre.common + + + com.bocloud + bocloud.public.provider + ${bocloud.cmp.version} + + + + com.tencentcloudapi + tencentcloud-sdk-java + 3.0.43 + + + com.qcloud + qcloud-java-sdk + 2.0.7 + + + + \ No newline at end of file diff --git a/src/main/java/com/bocloud/cmp/common/enums/TceActionEnum.java b/src/main/java/com/bocloud/cmp/common/enums/TceActionEnum.java new file mode 100644 index 0000000..6932595 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/common/enums/TceActionEnum.java @@ -0,0 +1,41 @@ +package com.bocloud.cmp.common.enums; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceAction + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/12/21 15:12 + */ +public enum TceActionEnum { + + LIST_SECURITY_GROUP("DescribeSecurityGroups"), + CREATE_SECURITY_GROUP("CreateSecurityGroup"), + REMOVE_SECURITY_GROUP("DeleteSecurityGroup"), + + LIST_SECURITY_GROUP_RULE("DescribeSecurityGroupPolicys"), + CREATE_SECURITY_GROUP_RULE("CreateSecurityGroupPolicy"), + REMOVE_SECURITY_GROUP_RULE("DeleteSecurityGroupPolicy"), + + LIST_VPC("DescribeVpcEx"), + CREATE_VPC("CreateVpc"), + REMOVE_VPC("DeleteVpc"), + MODIFY_VPC("ModifyVpcAttribute"), + + LIST_SUBNET("DescribeSubnetEx"), + CREATE_SUBNET("CreateSubnet"), + REMOVE_SUBNET("DeleteSubnet"), + + ResetInstancesPassword("ResetInstancesPassword"); + + + private final String value; + + TceActionEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/bocloud/cmp/common/enums/TceEnum.java b/src/main/java/com/bocloud/cmp/common/enums/TceEnum.java new file mode 100644 index 0000000..e6fbf08 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/common/enums/TceEnum.java @@ -0,0 +1,22 @@ +package com.bocloud.cmp.common.enums; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceEnum + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:53 + */ +public enum TceEnum { + VPC("vpc"), CVM("cvm"), CBS("cbs"), CLB("clb"), DFW("dfw"), EIP("eip"), BM("bm"), BILL("bill"); + + private final String value; + + TceEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/bocloud/cmp/provider/TceProvider.java b/src/main/java/com/bocloud/cmp/provider/TceProvider.java new file mode 100644 index 0000000..f075226 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/TceProvider.java @@ -0,0 +1,185 @@ +package com.bocloud.cmp.provider; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.provider.common.TceLocationProvider; +import com.tencentcloudapi.billing.v20180709.BillingClient; +import com.tencentcloudapi.bm.v20180423.BmClient; +import com.tencentcloudapi.cbs.v20170312.CbsClient; +import com.tencentcloudapi.clb.v20180317.ClbClient; +import com.tencentcloudapi.common.AbstractClient; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.profile.ClientProfile; +import com.tencentcloudapi.common.profile.HttpProfile; +import com.tencentcloudapi.cvm.v20170312.CvmClient; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesResponse; +import com.tencentcloudapi.vpc.v20170312.VpcClient; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: Tceprovider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class TceProvider extends GenericProvider implements SuperProvider { + + private static Logger logger = LoggerFactory.getLogger(TceProvider.class); + + private String secretId; + private String secretKey; + private Credential credential; + private String endpoint; // 平台地址 m14-2.tcecqpoc.fsphere.cn + private Butler butler; + private String projectId = "0"; // 默认项目 + private String regionId = "nanjing"; // 选择大区 + private ClientProfile clientProfile = new ClientProfile(); // 接入地域 + private HttpProfile httpProfile = new HttpProfile(); + private static final String HTTP = "http://"; + private static final Integer CONN_TIMEOUT = 60 * 10; + private static final String APIVERSION = "api3"; + protected static final Integer LIMIT = 50; + + /** + * 构造方法,所有的云平台驱动都必须要实现或重写该构造方法 + * + * @param butler + * 云平台认证信息 + */ + public TceProvider(Butler butler) { + super(butler); + this.secretId = butler.getAccessKey(); + this.secretKey = butler.getSecretKey(); + this.regionId = butler.getRegionId(); + this.credential = new Credential(secretId, secretKey); + this.endpoint = APIVERSION + '.' + butler.getUrl(); + this.butler = butler; + } + + private void configuration(TceEnum type) { + httpProfile.setConnTimeout(CONN_TIMEOUT); + httpProfile.setProtocol(HTTP); + httpProfile.setEndpoint(type.getValue() + '.' + endpoint); + clientProfile.setHttpProfile(httpProfile); + } + + public AbstractClient getClient(TceEnum type) { + AbstractClient abstractClient = null; + this.configuration(type); + switch (type) { + case CVM: + abstractClient = new CvmClient(credential, regionId, clientProfile); + break; + case CBS: + abstractClient = new CbsClient(credential, regionId, clientProfile); + break; + case VPC: + abstractClient = new VpcClient(credential, regionId, clientProfile); + break; + case CLB: + abstractClient = new ClbClient(credential, regionId, clientProfile); + break; + case BM: + abstractClient = new BmClient(credential, regionId, clientProfile); + break; + case BILL: + abstractClient = new BillingClient(credential, regionId, clientProfile); + break; + default: + break; + } + return abstractClient; + } + + public static void main(String[] args) { + Butler butler = new Butler(); + butler.setUrl("yf-1.tcepoc.fsphere.cn"); + butler.setSecretKey("mFPItB8l58vPr34tPdaEZcNpySdW7PO5"); + butler.setAccessKey("AKIDWQ7ZmofLp7B3kGZgbY5PSDelZ6MJwKRQ"); + butler.setRegionId("chongqing"); + TceLocationProvider provider = new TceLocationProvider(butler); + System.out.println(provider.sync()); + // TceProvider provider = new TceProvider(butler); + // BillingClient client = (BillingClient) provider.getClient(TceEnum.BILL); + // Long offset = 0L; + // DescribeBillDetailRequest req = new DescribeBillDetailRequest(); + // List billDetails = new ArrayList<>(); + // try { + // req.setOffset(offset); + // req.setBeginTime("2020-01-03 00:00:00"); + // req.setEndTime("2020-07-03 00:00:00"); + // req.setPeriodType("byPayTime"); + // req.setLimit(50L); + // DescribeBillDetailResponse response = client.DescribeBillDetail(req); + // System.out.println(response.getRequestId()); + // billDetails.addAll(Arrays.asList(response.getDetailSet())); + // // 循环分页查询 + // while (billDetails.size() >= LIMIT + offset) { + // req.setOffset(offset += LIMIT); + // response = client.DescribeBillDetail(req); + // billDetails.addAll(Arrays.asList(response.getDetailSet())); + // } + // System.out.println(JSONObject.toJSON(billDetails)); + // } catch (Exception e) { + // System.out.println(e.getMessage()); + // } + } + + @Override + public boolean accessable() { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeInstancesRequest req = new DescribeInstancesRequest(); + DescribeInstancesResponse response = client.DescribeInstances(req); + response.getInstanceSet(); + return true; + } catch (Exception e) { + logger.error("云平台(SDK)认证失败 :" + e.getMessage()); + return false; + } + } + + public String getSecretId() { + return secretId; + } + + public void setSecretId(String secretId) { + this.secretId = secretId; + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public Butler getButler() { + return butler; + } + + public void setButler(Butler butler) { + this.butler = butler; + } + + public String getRegionId() { + return regionId; + } + + public void setRegionId(String regionId) { + this.regionId = regionId; + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } +} diff --git a/src/main/java/com/bocloud/cmp/provider/TceRestApiProvider.java b/src/main/java/com/bocloud/cmp/provider/TceRestApiProvider.java new file mode 100644 index 0000000..47e3da3 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/TceRestApiProvider.java @@ -0,0 +1,187 @@ +package com.bocloud.cmp.provider; + +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceActionEnum; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.common.http.HttpClient; +import com.bocloud.common.utils.JSONTools; +import com.bocloud.common.utils.MapTools; +import org.apache.commons.codec.binary.Base64; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.TreeMap; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceRestApiProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class TceRestApiProvider extends GenericProvider implements SuperProvider { + + private static Logger logger = LoggerFactory.getLogger(TceRestApiProvider.class); + + private String secretId; + private String secretKey; + private Butler butler; + private String domain; + private String endpoint; // 平台地址 + // api2.m14-2.tcecqpoc.fsphere.cn/v2/index.php? + private String regionId = "nanjing"; + private String projectId = "0"; // 默认项目 + private static final String CHARSET = "UTF-8"; + private static final String HTTP = "http://"; + private static final String GET = "GET"; + private static final String APIVERSION = "api2"; + private static final String APISUFFIX = "/v2/index.php?"; + protected static final String MESSAGE = "message"; + protected static final Integer LIMIT = 50; // 腾讯资源查询时用来控制分页的参数,v3最大为100,v2最大为50 + protected static Integer subscript = 0; // 腾讯个别创建资源需要下标 + + public TceRestApiProvider(Butler butler) { + super(butler); + this.secretId = butler.getAccessKey(); + this.secretKey = butler.getSecretKey(); + this.regionId = butler.getRegionId(); + this.endpoint = APIVERSION + '.' + butler.getUrl() + APISUFFIX; + this.butler = butler; + } + + private void configuration(TceEnum type) { + this.domain = type.getValue() + '.' + endpoint; + } + + public boolean verify(JSONObject object) { + if (null == object || object.isEmpty()) { + return false; + } + return object.getInteger("code") == 0 && object.getString("codeDesc").equals("Success"); + } + + @Override + public boolean accessable() { + TreeMap params = new TreeMap<>(); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.LIST_VPC, params); + return this.verify(object); + } + + public JSONObject connection(TceEnum type, TceActionEnum action, TreeMap param) { + this.configuration(type);// 获取了连接域名 + return this.invoke(action.getValue(), this.domain, this.secretId, this.secretKey, this.regionId, HTTP, param); + } + + public JSONObject invoke(String action, String domain, String secretId, String secretKey, String region, + String http, TreeMap param) { + try { + TreeMap params = new TreeMap<>(); + params.put("Action", action); // 公共参数 + params.put("Nonce", (int) ((Math.random() * 9 + 1) * 10000)); // 公共参数 + params.put("Region", region); // 公共参数 + params.put("SecretId", secretId); // 公共参数 + params.put("Timestamp", System.currentTimeMillis() / 1000); + params.putAll(param); + String srcStr = getStringToSign(params, domain); + params.put("Signature", genHMAC(srcStr, secretKey)); + String url = getUrl(params, http + domain); + HttpClient httpClient = new HttpClient(); + return JSONTools.isJSONObj(httpClient.get(url).getMessage()); + } catch (Exception e) { + logger.error("云平台API连接失败: " + e.getMessage()); + return new JSONObject(MapTools.simpleMap(MESSAGE, e.getMessage())); + } + } + + // 公共方法-获取地址 通用 + public String getUrl(TreeMap params, String domain) throws UnsupportedEncodingException { + StringBuilder url = new StringBuilder(domain); + // 实际请求的url中对参数顺序没有要求 + for (String k : params.keySet()) { + // 需要对请求串进行urlencode,由于key都是英文字母,故此处仅对其value进行urlencode + url.append(k).append("=").append(URLEncoder.encode(params.get(k).toString(), CHARSET)).append("&"); + } + return url.toString().substring(0, url.length() - 1); + } + + // 公共方法-字典排序 通用 + public String getStringToSign(TreeMap params, String domain) { + StringBuilder s2s = new StringBuilder(GET + domain); + // 签名时要求对参数进行字典排序,此处用TreeMap保证顺序 + for (String k : params.keySet()) { + s2s.append(k).append("=").append(params.get(k).toString()).append("&"); + } + return s2s.toString().substring(0, s2s.length() - 1); + } + + public String genHMAC(String srcStr, String secretKey) throws Exception { + byte[] result = null; + // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称 + SecretKeySpec signinKey = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1"); + // 生成一个指定 Mac 算法 的 Mac 对象 + Mac mac = Mac.getInstance("HmacSHA1"); + // 用给定密钥初始化 Mac 对象 + mac.init(signinKey); + // 完成 Mac 操作 + byte[] rawHmac = mac.doFinal(srcStr.getBytes()); + result = Base64.encodeBase64(rawHmac); + if (null != result) { + return new String(result); + } else { + return null; + } + } + + public String getProjectId() { + return projectId; + } + + public void setProjectId(String projectId) { + this.projectId = projectId; + } + + public String getSecretId() { + return secretId; + } + + public void setSecretId(String secretId) { + this.secretId = secretId; + } + + public String getSecretKey() { + return secretKey; + } + + public void setSecretKey(String secretKey) { + this.secretKey = secretKey; + } + + public Butler getButler() { + return butler; + } + + public void setButler(Butler butler) { + this.butler = butler; + } + + public String getDomain() { + return domain; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getRegionId() { + return regionId; + } + + public void setRegionId(String regionId) { + this.regionId = regionId; + } +} diff --git a/src/main/java/com/bocloud/cmp/provider/common/TceAuthProvider.java b/src/main/java/com/bocloud/cmp/provider/common/TceAuthProvider.java new file mode 100644 index 0000000..8e9deb6 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/common/TceAuthProvider.java @@ -0,0 +1,30 @@ +package com.bocloud.cmp.provider.common; + +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.provider.TceRestApiProvider; +import com.bocloud.cmp.provider.network.TceVpcProvider; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceAuthProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceAuthProvider extends TceRestApiProvider implements AuthProvider { + + public TceAuthProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult auth() { + TceVpcProvider provider = new TceVpcProvider(this.getButler()); + BocloudResult result = provider.list(); + result = new BocloudResult(result.isSuccess(), result.getMessage()); + return result; + } +} diff --git a/src/main/java/com/bocloud/cmp/provider/common/TceFlavorProvider.java b/src/main/java/com/bocloud/cmp/provider/common/TceFlavorProvider.java new file mode 100644 index 0000000..e8ac432 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/common/TceFlavorProvider.java @@ -0,0 +1,113 @@ +package com.bocloud.cmp.provider.common; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.FlavorModel; +import com.bocloud.cmp.provider.TceProvider; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.cmp.tceconvertor.FlavorConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; +import com.tencentcloudapi.cvm.v20170312.CvmClient; +import com.tencentcloudapi.cvm.v20170312.models.DescribeZoneInstanceConfigInfosRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeZoneInstanceConfigInfosResponse; +import com.tencentcloudapi.cvm.v20170312.models.Filter; +import com.tencentcloudapi.cvm.v20170312.models.InstanceTypeConfig; +import com.tencentcloudapi.cvm.v20170312.models.InstanceTypeQuotaItem; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceFlavorProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceFlavorProvider extends TceProvider implements FlavorProvider { + + private static Logger logger = LoggerFactory.getLogger(TceFlavorProvider.class); + + private BeanConvertor convertor = new FlavorConvertor(); + + public TceFlavorProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult sync() { + BocloudResult result; + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeZoneInstanceConfigInfosRequest req = new DescribeZoneInstanceConfigInfosRequest(); + Filter f1 = new Filter(); + f1.setName("instance-charge-type"); + // PREPAID:表示预付费,即包年包月 | POSTPAID_BY_HOUR:表示后付费,即按量计费 + f1.setValues(new String[] { "POSTPAID_BY_HOUR" }); + Filter[] filters = new Filter[] { f1 }; + req.setFilters(filters); + DescribeZoneInstanceConfigInfosResponse resp = client.DescribeZoneInstanceConfigInfos(req); + result = new BocloudResult(true, convertList(Arrays.asList(resp.getInstanceTypeQuotaSet())), + "list flavor success!"); + } catch (Exception e) { + logger.error("list flavor error :", e.getMessage()); + result = new BocloudResult(false, e.getMessage()); + } + return result; + } + + public List convertList(List objects) { + List regionModels = new ArrayList<>(); + for (InstanceTypeQuotaItem object : objects) { + String zone = object.getZone(); + if (StringUtils.isEmpty(zone)) { + continue; + } + String status = object.getStatus(); + if ("SELL".equalsIgnoreCase(status)) { + regionModels.add(convertModel(object)); + } + } + return regionModels; + } + + public FlavorModel convertModel(InstanceTypeQuotaItem info) { + FlavorModel model = new FlavorModel(); + if (null != info) { + model.setCpu(info.getCpu()); + model.setMemory(BigDecimal.valueOf(info.getMemory())); + model.setName(info.getTypeName()); + model.setFamily(info.getInstanceFamily()); + model.setFlavorUuid(info.getInstanceType()); + model.setDisk(info.getNetworkCard()); + model.setInstanceChargeType(info.getInstanceChargeType()); + model.setStatus(info.getStatus()); + model.setZone(info.getZone()); + } + return model; + } + + @Override + public BocloudResult create(FlavorModel flavor) { + return null; + } + + @Override + public BocloudResult remove(String flavorId) { + return null; + } + + @Override + public BocloudResult update(FlavorModel flavorModel) { + return null; + } + +} diff --git a/src/main/java/com/bocloud/cmp/provider/common/TceLocationProvider.java b/src/main/java/com/bocloud/cmp/provider/common/TceLocationProvider.java new file mode 100644 index 0000000..0113a38 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/common/TceLocationProvider.java @@ -0,0 +1,285 @@ +package com.bocloud.cmp.provider.common; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.FlavorModel; +import com.bocloud.cmp.model.HostModel; +import com.bocloud.cmp.model.ImageModel; +import com.bocloud.cmp.model.KeypairModel; +import com.bocloud.cmp.model.RegionModel; +import com.bocloud.cmp.model.SecurityGroupModel; +import com.bocloud.cmp.model.SecurityGroupRuleModel; +import com.bocloud.cmp.model.ServerModel; +import com.bocloud.cmp.model.SnapshotModel; +import com.bocloud.cmp.model.SubnetModel; +import com.bocloud.cmp.model.TceSyncModel; +import com.bocloud.cmp.model.VolumeModel; +import com.bocloud.cmp.model.VpcModel; +import com.bocloud.cmp.model.ZoneModel; +import com.bocloud.cmp.provider.TceProvider; +import com.bocloud.cmp.provider.compute.ImageProvider; +import com.bocloud.cmp.provider.compute.ServerProvider; +import com.bocloud.cmp.provider.compute.SnapshotProvider; +import com.bocloud.cmp.provider.compute.TceImageProvider; +import com.bocloud.cmp.provider.compute.TceServerProvider; +import com.bocloud.cmp.provider.compute.TceSnapshotProvider; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.cmp.provider.network.SecurityGroupProvider; +import com.bocloud.cmp.provider.network.SecurityGroupRuleProvider; +import com.bocloud.cmp.provider.network.SubnetProvider; +import com.bocloud.cmp.provider.network.TceSecuGroupProvider; +import com.bocloud.cmp.provider.network.TceSecuGroupRuleProvider; +import com.bocloud.cmp.provider.network.TceSubnetProvider; +import com.bocloud.cmp.provider.network.TceVpcProvider; +import com.bocloud.cmp.provider.network.VpcProvider; +import com.bocloud.cmp.provider.security.KeypairProvider; +import com.bocloud.cmp.provider.security.TceKeypairProvider; +import com.bocloud.cmp.provider.storage.TceVolumeProvider; +import com.bocloud.cmp.provider.storage.VolumeProvider; +import com.bocloud.cmp.tceconvertor.RegionConvertor; +import com.bocloud.cmp.tceconvertor.ZoneConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; +import com.tencentcloudapi.cvm.v20170312.CvmClient; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesStatusRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesStatusResponse; +import com.tencentcloudapi.cvm.v20170312.models.DescribeRegionsRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeRegionsResponse; +import com.tencentcloudapi.cvm.v20170312.models.DescribeZonesRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeZonesResponse; +import com.tencentcloudapi.cvm.v20170312.models.InstanceStatus; +import com.tencentcloudapi.cvm.v20170312.models.RegionInfo; +import com.tencentcloudapi.cvm.v20170312.models.ZoneInfo; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TencentLocationProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceLocationProvider extends TceProvider implements LocationProvider { + + private static Logger logger = LoggerFactory.getLogger(TceLocationProvider.class); + + private Butler butler; + private FlavorProvider flavorProvider = null; + private ImageProvider imageProvider = null; + private KeypairProvider keypairProvider = null; + private SecurityGroupProvider secgProvider = null; + private ServerProvider serverProvider = null; + private SnapshotProvider snapshotProvider = null; + private SubnetProvider subnetProvider = null; + private VolumeProvider volumeProvider = null; + private VpcProvider vpcProvider = null; + private SecurityGroupRuleProvider securityGroupRuleProvider = null; + + public TceLocationProvider(Butler butler) { + super(butler); + this.butler = butler; + } + + private BeanConvertor regionConvertor = new RegionConvertor(); + private BeanConvertor zoneConvertor = new ZoneConvertor(); + + @Override + public BocloudResult sync() { + try { + flavorProvider = new TceFlavorProvider(butler); + imageProvider = new TceImageProvider(butler); + keypairProvider = new TceKeypairProvider(butler); + serverProvider = new TceServerProvider(butler); + snapshotProvider = new TceSnapshotProvider(butler); + volumeProvider = new TceVolumeProvider(butler); + vpcProvider = new TceVpcProvider(butler); + subnetProvider = new TceSubnetProvider(butler); + secgProvider = new TceSecuGroupProvider(butler); + securityGroupRuleProvider = new TceSecuGroupRuleProvider(butler); + + TceSyncModel syncModel = new TceSyncModel(); + List regions = new ArrayList<>(); + List flavorModels = new ArrayList<>(); + List imageModels = new ArrayList<>(); + List vpcModels = new ArrayList<>(); + List securityGroupModels = new ArrayList<>(); + List volumeModels = new ArrayList<>(); + List serverModels = new ArrayList<>(); + List snapshotModels = new ArrayList<>(); + List subnetModels = new ArrayList<>(); + List keypairModels = new ArrayList<>(); + + logger.info("{} 地域 同步-->Start", this.butler.getName()); + RegionModel regionModel = new RegionModel(); + regionModel.setCode(this.getRegionId()); + if (!StringUtils.isEmpty(this.getRegionId())) { + BocloudResult listZones = this.listZones(this.getRegionId()); + regionModel.setZones(JSONObject.parseArray(JSONObject.toJSONString(listZones.getData()), + ZoneModel.class)); + } + regions.add(regionModel); + logger.info("{} 地域 同步-->End", this.butler.getName()); + Map zoneMap = new HashMap<>(); + Optional.ofNullable(regionModel.getZones()).ifPresent( + zones -> zones.stream().forEach(zone -> zoneMap.put(zone.getZoneNum(), zone.getZoneId()))); + logger.info("{} 规格 同步-->Start", this.butler.getName()); + BocloudResult flavorResult = flavorProvider.sync(); + if (flavorResult.isSuccess()) { + flavorModels = JSONObject + .parseArray(JSONObject.toJSONString(flavorResult.getData()), FlavorModel.class); + } + logger.info("{} 规格 同步-->End", this.butler.getName()); + logger.info("{} 镜像 同步-->Start", this.butler.getName()); + BocloudResult imageResult = imageProvider.list(); + if (imageResult.isSuccess()) { + imageModels = JSONObject.parseArray(JSONObject.toJSONString(imageResult.getData()), ImageModel.class); + } + logger.info("{} 镜像 同步-->End", this.butler.getName()); + logger.info("{} 硬盘 同步-->Start", this.butler.getName()); + BocloudResult volumeResult = volumeProvider.list(); + if (volumeResult.isSuccess()) { + volumeModels = JSONObject + .parseArray(JSONObject.toJSONString(volumeResult.getData()), VolumeModel.class); + } + logger.info("{} 硬盘 同步-->End", this.butler.getName()); + logger.info("{} 快照 同步-->Start", this.butler.getName()); + BocloudResult snapshotResult = snapshotProvider.list(); + if (snapshotResult.isSuccess()) { + snapshotModels = JSONObject.parseArray(JSONObject.toJSONString(snapshotResult.getData()), + SnapshotModel.class); + } + logger.info("{} 快照 同步-->End", this.butler.getName()); + logger.info("{} 密钥 同步-->Start", this.butler.getName()); + BocloudResult keypairResult = keypairProvider.list(); + if (keypairResult.isSuccess()) { + keypairModels = JSONObject.parseArray(JSONObject.toJSONString(keypairResult.getData()), + KeypairModel.class); + } + logger.info("{} 密钥 同步-->End", this.butler.getName()); + logger.info("{} vpc 同步-->Start", this.butler.getName()); + BocloudResult vpcResult = vpcProvider.list(); + if (vpcResult.isSuccess()) { + vpcModels = JSONObject.parseArray(JSONObject.toJSONString(vpcResult.getData()), VpcModel.class); + } + logger.info("{} vpc 同步-->End", this.butler.getName()); + logger.info("{} 子网 同步-->Start", this.butler.getName()); + BocloudResult subnetResult = subnetProvider.list(); + if (subnetResult.isSuccess()) { + subnetModels = JSONObject + .parseArray(JSONObject.toJSONString(subnetResult.getData()), SubnetModel.class); + subnetModels.stream().forEach(model -> model.setZone(zoneMap.get(model.getZoneNum()))); + } + logger.info("{} 子网 同步-->End", this.butler.getName()); + logger.info("{} 安全组 同步-->Start", this.butler.getName()); + BocloudResult securityResult = secgProvider.list(); + if (securityResult.isSuccess()) { + securityGroupModels = JSONObject.parseArray(JSONObject.toJSONString(securityResult.getData()), + SecurityGroupModel.class); + securityGroupModels.stream().forEach( + model -> { + BocloudResult secRuleResult = securityGroupRuleProvider.list(model.getGroupUuid()); + if (secRuleResult.isSuccess()) { + model.setModels(JSONObject.parseArray(JSONObject.toJSONString(secRuleResult.getData()), + SecurityGroupRuleModel.class)); + } + }); + } + logger.info("{} 安全组 同步-->End", this.butler.getName()); + logger.info("{} 虚拟机 同步-->Start", this.butler.getName()); + BocloudResult serverResult = serverProvider.list(); + if (serverResult.isSuccess()) { + serverModels = JSONObject + .parseArray(JSONObject.toJSONString(serverResult.getData()), ServerModel.class); + // for (ServerModel serverModel : serverModels) { + // BocloudResult statusResult = + // this.instancesStatus(serverModel.getInstanceId()); + // String serverStatus = (String) statusResult.getData(); + // serverModel.setStatus(serverStatus); + // } + } + logger.info("{} 虚拟机 同步-->End", this.butler.getName()); + syncModel.setFlavorModels(flavorModels); + syncModel.setRegionModels(regions); + syncModel.setImageModels(imageModels); + syncModel.setServerModels(serverModels); + syncModel.setVolumeModels(volumeModels); + syncModel.setSnapshotModels(snapshotModels); + syncModel.setVpcModels(vpcModels); + syncModel.setSubnetModels(subnetModels); + syncModel.setSecurityGroupModels(securityGroupModels); + syncModel.setKeypairModels(keypairModels); + return new BocloudResult(true, syncModel, "success"); + } catch (Exception e) { + logger.error("TCE同步失败: " + e); + return new BocloudResult(false, e.getMessage(), "TCE同步失败"); + } + } + + @Override + public BocloudResult listRegions() { + try { + DescribeRegionsRequest req = DescribeRegionsRequest.fromJsonString("{}", DescribeRegionsRequest.class); + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeRegionsResponse resp = client.DescribeRegions(req); + RegionInfo[] regionSet = resp.getRegionSet(); + return new BocloudResult(true, regionConvertor.convertList(Arrays.asList(regionSet)), "查询成功"); + } catch (Exception e) { + logger.error("查询失败: " + e); + return new BocloudResult(false, e.getMessage(), "查询失败"); + } + } + + @Override + public BocloudResult listZones(String region) { + try { + DescribeZonesRequest req = new DescribeZonesRequest(); + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + client.setRegion(region); + DescribeZonesResponse resp = client.DescribeZones(req); + ZoneInfo[] zoneSet = resp.getZoneSet(); + return new BocloudResult(true, zoneConvertor.convertList(Arrays.asList(zoneSet)), "查询成功"); + } catch (Exception e) { + logger.error("查询失败 : " + e); + return new BocloudResult(false, e.getMessage(), "查询失败"); + } + } + + @Override + public BocloudResult syncPortByNetworkUuid(String networkUuid) { + return null; + } + + @Override + public BocloudResult getHostModel(HostModel arg0) { + return null; + } + + // 用于查询主机开关机状态 + private BocloudResult instancesStatus(String instancesId) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeInstancesStatusRequest req = new DescribeInstancesStatusRequest(); + req.setInstanceIds(new String[] { instancesId }); + DescribeInstancesStatusResponse resp = client.DescribeInstancesStatus(req); + InstanceStatus[] instanceStatusSet = resp.getInstanceStatusSet(); + InstanceStatus instanceStatus = instanceStatusSet[0]; + return new BocloudResult(true, instanceStatus.getInstanceState(), "查询状态成功"); + } catch (Exception e) { + logger.error("查询状态失败: " + e); + return new BocloudResult(false, "查询状态失败", e.getMessage()); + } + } + +} diff --git a/src/main/java/com/bocloud/cmp/provider/compute/TceImageProvider.java b/src/main/java/com/bocloud/cmp/provider/compute/TceImageProvider.java new file mode 100644 index 0000000..54f3588 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/compute/TceImageProvider.java @@ -0,0 +1,227 @@ +package com.bocloud.cmp.provider.compute; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.ImageModel; +import com.bocloud.cmp.provider.TceProvider; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.cmp.tceconvertor.ImageConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; +import com.tencentcloudapi.cvm.v20170312.CvmClient; +import com.tencentcloudapi.cvm.v20170312.models.CreateImageRequest; +import com.tencentcloudapi.cvm.v20170312.models.DeleteImagesRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeImagesRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeImagesResponse; +import com.tencentcloudapi.cvm.v20170312.models.Filter; +import com.tencentcloudapi.cvm.v20170312.models.Image; +import com.tencentcloudapi.cvm.v20170312.models.ModifyImageAttributeRequest; +import com.tencentcloudapi.cvm.v20170312.models.ModifyImageSharePermissionRequest; +import com.tencentcloudapi.cvm.v20170312.models.SyncImagesRequest; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceImageProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceImageProvider extends TceProvider implements ImageProvider { + + public TceImageProvider(Butler butler) { + super(butler); + } + + private static Logger logger = LoggerFactory.getLogger(TceImageProvider.class); + + private BeanConvertor convertor = new ImageConvertor(); + + @Override + public BocloudResult list() { + Integer offset = 0; + BocloudResult result; + DescribeImagesRequest imageRequest = new DescribeImagesRequest(); + List images = new ArrayList<>(); + try { + imageRequest.setLimit(LIMIT); + DescribeImagesResponse response = ((CvmClient) this.getClient(TceEnum.CVM)).DescribeImages(imageRequest); + images.addAll(Arrays.asList(response.getImageSet())); + // 循环分页查询 + while (images.size() >= LIMIT + offset) { + imageRequest.setOffset(offset += LIMIT); + response = ((CvmClient) this.getClient(TceEnum.CVM)).DescribeImages(imageRequest); + images.addAll(Arrays.asList(response.getImageSet())); + } + result = new BocloudResult(true, convertor.convertList(images), "success"); + } catch (Exception e) { + logger.error("list images error:", e.getMessage()); + result = new BocloudResult(false, e.getMessage()); + } + return result; + } + + @Override + public BocloudResult detail(String imageId) { + try { + DescribeImagesRequest req = new DescribeImagesRequest(); + req.setImageIds(new String[] { imageId }); + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeImagesResponse resp = client.DescribeImages(req); + ImageModel imageModel = convertor.convertModel(resp.getImageSet()[0]); + imageModel.setRegionId(this.getRegionId()); + return new BocloudResult(true, imageModel, "detail image success!"); + } catch (Exception e) { + logger.error("detail image error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult remove(String imageId) { + try { + DeleteImagesRequest req = new DeleteImagesRequest(); + req.setImageIds(new String[] { imageId }); + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + client.DeleteImages(req); + return new BocloudResult(true, "remove image success!"); + } catch (Exception e) { + String message = e.getMessage(); + if (null != message && message.contains("")) { + return new BocloudResult(true, "删除成功!"); + } + logger.error("remove image error :", message); + return new BocloudResult(false, message); + } + } + + @Override + public BocloudResult modify(ImageModel image) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ModifyImageAttributeRequest request = new ModifyImageAttributeRequest(); + request.setImageId(image.getImageUuid()); + if (!StringUtils.isEmpty(image.getName())) { + request.setImageName(image.getName()); + } + if (!StringUtils.isEmpty(image.getRemark())) { + request.setImageDescription(image.getRemark()); + } + client.ModifyImageAttribute(request); + return new BocloudResult(true, this.detail(image.getImageUuid()).getData(), "update image success!"); + } catch (Exception e) { + logger.error("update image error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + public Image getImages(String imageName, String region) { + Image image = null; + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + if (!StringUtils.isEmpty(region)) { + client.setRegion(region); + } + // 加入筛选条件 + DescribeImagesRequest req = new DescribeImagesRequest(); + Filter filter = new Filter(); + filter.setName("image-type"); + filter.setValues(new String[] { "PRIVATE_IMAGE" }); + Filter[] filters = new Filter[] { filter }; + req.setFilters(filters); + Long startTime = System.currentTimeMillis(); + Long endTime = System.currentTimeMillis(); + while (endTime - startTime < 5 * 60 * 1000) { + // 创建时间不确定,增加休眠减少轮询次数 + Thread.sleep(6000); + DescribeImagesResponse response = client.DescribeImages(req); + Image[] images = response.getImageSet(); + if (null == images || images.length <= 0) { + logger.error("data does not exist :", imageName); + break; + } + for (Image img : images) { + if (imageName.equalsIgnoreCase(img.getImageName()) + && "NORMAL".equalsIgnoreCase(img.getImageState())) { + image = img; + break; + } + } + if (!ObjectUtils.isEmpty(image)) { + break; + } + endTime = System.currentTimeMillis(); + } + } catch (Exception e) { + logger.error("image get status error: " + e.getMessage()); + } + return image; + } + + @Override + public BocloudResult create(ImageModel imageModel) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + CreateImageRequest req = new CreateImageRequest(); + req.setInstanceId(imageModel.getInstanceId()); + req.setImageName(imageModel.getName()); + req.setImageDescription(imageModel.getRemark()); + client.CreateImage(req); + Image image = getImages(imageModel.getName(), null); + if (!ObjectUtils.isEmpty(image)) { + ImageModel model = convertor.convertModel(image); + model.setRegionId(this.getRegionId()); + return new BocloudResult(true, model, "create image success!"); + } else { + return new BocloudResult(false, "create image timeout! "); + } + } catch (Exception e) { + logger.error("create image error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult shareImage(ImageModel imageModel) { + try { + ModifyImageSharePermissionRequest request = new ModifyImageSharePermissionRequest(); + request.setImageId(imageModel.getImageUuid()); + request.setAccountIds(imageModel.getAccountIds()); + request.setPermission(imageModel.getPermission()); + ((CvmClient) this.getClient(TceEnum.CVM)).ModifyImageSharePermission(request); + return new BocloudResult(true, "share image success!"); + } catch (Exception e) { + logger.error("share image error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult syncImages(ImageModel imageModel) { + try { + SyncImagesRequest request = new SyncImagesRequest(); + request.setDestinationRegions(new String[] { imageModel.getRegionId() }); + request.setImageIds(new String[] { imageModel.getImageUuid() }); + ((CvmClient) this.getClient(TceEnum.CVM)).SyncImages(request); + Image image = this.getImages(imageModel.getName(), imageModel.getRegionId()); + if (!ObjectUtils.isEmpty(image)) { + return new BocloudResult(true, convertor.convertModel(image), "cross-domain image success!"); + } else { + return new BocloudResult(false, "cross-domain image timeout! "); + } + } catch (Exception e) { + logger.error("cross-domain image error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + +} diff --git a/src/main/java/com/bocloud/cmp/provider/compute/TceServerProvider.java b/src/main/java/com/bocloud/cmp/provider/compute/TceServerProvider.java new file mode 100644 index 0000000..56b5b9d --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/compute/TceServerProvider.java @@ -0,0 +1,829 @@ +package com.bocloud.cmp.provider.compute; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.TreeMap; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceActionEnum; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.OSMigrateModel; +import com.bocloud.cmp.model.ServerModel; +import com.bocloud.cmp.model.SnapshotModel; +import com.bocloud.cmp.model.VolumeModel; +import com.bocloud.cmp.model.h3c.H3cMigrateModel; +import com.bocloud.cmp.model.h3c.H3cServerModel; +import com.bocloud.cmp.provider.TceProvider; +import com.bocloud.cmp.provider.TceRestApiProvider; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.cmp.provider.storage.TceVolumeProvider; +import com.bocloud.cmp.tceconvertor.ServerConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; +import com.tencentcloudapi.cvm.v20170312.CvmClient; +import com.tencentcloudapi.cvm.v20170312.models.AssociateInstancesKeyPairsRequest; +import com.tencentcloudapi.cvm.v20170312.models.DataDisk; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesResponse; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesStatusRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeInstancesStatusResponse; +import com.tencentcloudapi.cvm.v20170312.models.DisassociateInstancesKeyPairsRequest; +import com.tencentcloudapi.cvm.v20170312.models.Instance; +import com.tencentcloudapi.cvm.v20170312.models.InstanceChargePrepaid; +import com.tencentcloudapi.cvm.v20170312.models.InstanceStatus; +import com.tencentcloudapi.cvm.v20170312.models.InternetAccessible; +import com.tencentcloudapi.cvm.v20170312.models.LoginSettings; +import com.tencentcloudapi.cvm.v20170312.models.ModifyInstancesAttributeRequest; +import com.tencentcloudapi.cvm.v20170312.models.Placement; +import com.tencentcloudapi.cvm.v20170312.models.RebootInstancesRequest; +import com.tencentcloudapi.cvm.v20170312.models.ResetInstanceRequest; +import com.tencentcloudapi.cvm.v20170312.models.ResetInstancesInternetMaxBandwidthRequest; +import com.tencentcloudapi.cvm.v20170312.models.ResetInstancesTypeRequest; +import com.tencentcloudapi.cvm.v20170312.models.ResizeInstanceDisksRequest; +import com.tencentcloudapi.cvm.v20170312.models.RunInstancesRequest; +import com.tencentcloudapi.cvm.v20170312.models.RunInstancesResponse; +import com.tencentcloudapi.cvm.v20170312.models.StartInstancesRequest; +import com.tencentcloudapi.cvm.v20170312.models.StopInstancesRequest; +import com.tencentcloudapi.cvm.v20170312.models.SystemDisk; +import com.tencentcloudapi.cvm.v20170312.models.TerminateInstancesRequest; +import com.tencentcloudapi.cvm.v20170312.models.VirtualPrivateCloud; +import com.tencentcloudapi.vpc.v20170312.VpcClient; +import com.tencentcloudapi.vpc.v20170312.models.AssociateAddressRequest; +import com.tencentcloudapi.vpc.v20170312.models.DisassociateAddressRequest; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceServerProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceServerProvider extends TceProvider implements ServerProvider { + + private static Logger logger = LoggerFactory.getLogger(TceServerProvider.class); + + private BeanConvertor convertor = new ServerConvertor(); + + private Butler butler; + + public TceServerProvider(Butler butler) { + super(butler); + this.butler = butler; + } + + @Override + public BocloudResult list() { + Integer offset = 0; + DescribeInstancesRequest req = new DescribeInstancesRequest(); + List instances = new ArrayList<>(); + try { + req.setLimit(LIMIT); + DescribeInstancesResponse response = ((CvmClient) this.getClient(TceEnum.CVM)).DescribeInstances(req); + instances.addAll(Arrays.asList(response.getInstanceSet())); + // 循环分页查询 + while (instances.size() >= LIMIT + offset) { + req.setOffset(offset += LIMIT); + response = ((CvmClient) this.getClient(TceEnum.CVM)).DescribeInstances(req); + instances.addAll(Arrays.asList(response.getInstanceSet())); + } + List models = convertor.convertList(instances); + Optional.ofNullable(models).ifPresent( + serverModels -> serverModels.stream().forEach( + serverModel -> serverModel.setRegionId(this.getRegionId()))); + return new BocloudResult(true, models, "list cloudServer success!"); + } catch (Exception e) { + logger.error("list cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + public BocloudResult getInstances(String instanceId) { + BocloudResult result = new BocloudResult(false, "data does not exist"); + try { + Long startTime = System.currentTimeMillis(); + Long endTime = System.currentTimeMillis(); + // 轮询5m + while (endTime - startTime < 5 * 60 * 1000) { + // 主机创建时间不确定,增加休眠减少轮询次数 + Thread.sleep(6000); + BocloudResult detail = this.detail(instanceId); + ServerModel model = JSONObject + .parseObject(JSONObject.toJSONString(detail.getData()), ServerModel.class); + if (ObjectUtils.isEmpty(model)) { + break; + } + if ("RUNNING".equalsIgnoreCase(model.getStatus()) || "STOPED".equalsIgnoreCase(model.getStatus()) + || "STOPPED".equalsIgnoreCase(model.getStatus())) { + result = this.detail(instanceId); + break; + } + endTime = System.currentTimeMillis(); + } + } catch (Exception e) { + logger.error("create server get status error: " + e.getMessage()); + result = new BocloudResult(false, "tce server get status error: " + e.getMessage()); + } + return result; + } + + // 私有云5月份版本查询主机详情没有主机状态,12月份查询后有该状态,暂时还是以5月版本为主 + public BocloudResult getStatusInstances(String instanceId) { + BocloudResult result = new BocloudResult(false, "server data does not exist"); + try { + Long startTime = System.currentTimeMillis(); + Long endTime = System.currentTimeMillis(); + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeInstancesStatusRequest request = new DescribeInstancesStatusRequest(); + request.setInstanceIds(new String[] { instanceId }); + while (endTime - startTime < 5 * 60 * 1000) { + Thread.sleep(6000); + DescribeInstancesStatusResponse resp = client.DescribeInstancesStatus(request); + InstanceStatus[] instanceStatusSet = resp.getInstanceStatusSet(); + if (instanceStatusSet == null || instanceStatusSet.length <= 0) { + break; + } + InstanceStatus instanceStatus = instanceStatusSet[0]; + if ("RUNNING".equalsIgnoreCase(instanceStatus.getInstanceState()) + || "STOPED".equalsIgnoreCase(instanceStatus.getInstanceState()) + || "STOPPED".equalsIgnoreCase(instanceStatus.getInstanceState())) { + result = this.getStatusDetail(instanceId, instanceStatus.getInstanceState()); + break; + } + endTime = System.currentTimeMillis(); + } + } catch (Exception e) { + logger.error("server status get status error: " + e.getMessage()); + result = new BocloudResult(false, "server status get status error: " + e.getMessage()); + } + return result; + } + + @Override + public BocloudResult create(ServerModel server) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + if (!StringUtils.isEmpty(server.getRegionId())) { + client.setRegion(server.getRegionId()); + } + RunInstancesRequest req = new RunInstancesRequest(); + // 付费方式 PREPAID:预付费,即包年包月 POSTPAID_BY_HOUR:按小时后付费 + String instanceChargeType = server.getInstanceChargeType(); + if (StringUtils.isEmpty(instanceChargeType)) { + instanceChargeType = "POSTPAID_BY_HOUR"; + } + req.setInstanceChargeType(instanceChargeType); + // 购买时长 + if ("PREPAID".equals(instanceChargeType)) { + InstanceChargePrepaid instanceChargePrepaid = new InstanceChargePrepaid(); + instanceChargePrepaid.setPeriod(Integer.valueOf(server.getInstancePeriod())); + /** + * •NOTIFY_AND_AUTO_RENEW:通知过期且自动续费 + * •NOTIFY_AND_MANUAL_RENEW:通知过期不自动续费 + * •DISABLE_NOTIFY_AND_MANUAL_RENEW:不通知过期不自动续费 + * 默认取值:NOTIFY_AND_MANUAL_RENEW + * 。若该参数指定为NOTIFY_AND_AUTO_RENEW,在账户余额充足的情况下,实例到期后将按月自动续费。 + */ + if (!StringUtils.isEmpty(server.getInstanceRenewFlag())) { + instanceChargePrepaid.setRenewFlag(server.getInstanceRenewFlag()); + } + req.setInstanceChargePrepaid(instanceChargePrepaid); + } + // 地区 项目 + Placement placement = new Placement(); + placement.setZone(server.getZone()); + if (!StringUtils.isEmpty(this.getProjectId())) { + placement.setProjectId(Integer.valueOf(this.getProjectId())); + } + req.setPlacement(placement); + req.setImageId(server.getImageUuid()); + if (!StringUtils.isEmpty(server.getName())) { + req.setInstanceName(server.getName()); + } + if (!StringUtils.isEmpty(server.getFlavorUuid())) { + req.setInstanceType(server.getFlavorUuid()); // 规格 + } + // LOCAL_BASIC:本地硬盘 || LOCAL_SSD:本地SSD硬盘 || CLOUD_BASIC:普通云硬盘 || + // CLOUD_SSD:SSD云硬盘 || CLOUD_PREMIUM:高性能云硬盘 + SystemDisk systemDisk = new SystemDisk(); + systemDisk.setDiskSize(Integer.valueOf(server.getSystemDiskSize())); + // 默认SSD云硬盘 + if (!StringUtils.isEmpty(server.getSystemDiskCategory())) { + systemDisk.setDiskType(server.getSystemDiskCategory()); + } + req.setSystemDisk(systemDisk); + // volume + List diskDevices = server.getDiskDevices(); + if (!CollectionUtils.isEmpty(diskDevices)) { + DataDisk disk = null; + List diskList = new ArrayList<>(); + for (VolumeModel volumeModel : diskDevices) { + disk = new DataDisk(); + disk.setDiskSize(Integer.valueOf(volumeModel.getSize())); + diskList.add(disk); + } + DataDisk[] dataDisks = new DataDisk[diskList.size()]; + req.setDataDisks(diskList.toArray(dataDisks)); + } + // vpc + String subnetUuid = server.getSubnetUuid(); + String networkUuid = server.getNetworkUuid(); + if (null != subnetUuid && null != networkUuid) { + VirtualPrivateCloud virtualPrivateCloud = new VirtualPrivateCloud(); + virtualPrivateCloud.setSubnetId(server.getSubnetUuid()); + virtualPrivateCloud.setVpcId(server.getNetworkUuid()); + virtualPrivateCloud.setAsVpcGateway(true); + req.setVirtualPrivateCloud(virtualPrivateCloud); + } + Integer count = server.getCount(); + if (null == count || count <= 0) { + count = 1; + } + req.setInstanceCount(Integer.valueOf(count)); + // 登录方式 + LoginSettings loginSettings = new LoginSettings(); + String password = server.getPassword(); + if (!StringUtils.isEmpty(password)) { + loginSettings.setPassword(password); + } + String keypairId = server.getKeypairName(); + if (!StringUtils.isEmpty(keypairId)) { + loginSettings.setKeyIds(new String[] { keypairId }); + } + req.setLoginSettings(loginSettings); + + List securityGroups = server.getSecurityGroups(); + if (!CollectionUtils.isEmpty(securityGroups)) { + String[] securityGroupIds = new String[securityGroups.size()]; + req.setSecurityGroupIds(securityGroups.toArray(securityGroupIds)); + } + RunInstancesResponse resp = client.RunInstances(req); + String[] instanceIdSet = resp.getInstanceIdSet(); + return getStatusInstances(instanceIdSet[0]); + } catch (Exception e) { + logger.error("create cloudServer error:{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult modify(ServerModel server) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ModifyInstancesAttributeRequest req = new ModifyInstancesAttributeRequest(); + req.setInstanceIds(new String[] { server.getInstanceId() }); + String name = server.getName(); + if (!StringUtils.isEmpty(name)) { + req.setInstanceName(name); + } + List securityGroups = server.getSecurityGroups(); + if (!CollectionUtils.isEmpty(securityGroups)) { + String[] groups = new String[securityGroups.size()]; + req.setSecurityGroups(securityGroups.toArray(groups)); + } + client.ModifyInstancesAttribute(req); + BocloudResult detail = this.detail(server.getInstanceId()); + return new BocloudResult(true, detail.getData(), "修改成功"); + } catch (Exception e) { + logger.error("modify cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult migrate(ServerModel server) { + // TODO Auto-generated method stub + return null; + } + + @Override + public BocloudResult migrate(OSMigrateModel model) { + // TODO Auto-generated method stub + return null; + } + + @Override + public BocloudResult remove(String instanceId, String name) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + TerminateInstancesRequest request = new TerminateInstancesRequest(); + request.setInstanceIds(new String[] { instanceId }); + client.TerminateInstances(request); + return new BocloudResult(true, "remove cloudServer success!"); + } catch (Exception e) { + logger.error("remove cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult detail(String instanceId) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeInstancesRequest req = new DescribeInstancesRequest(); + req.setInstanceIds(new String[] { instanceId }); + DescribeInstancesResponse resp = client.DescribeInstances(req); + Instance[] instanceSet = resp.getInstanceSet(); + ServerModel convertModel = null; + if (null != instanceSet && instanceSet.length > 0) { + Instance instance = instanceSet[0]; + convertModel = convertor.convertModel(instance); + convertModel.setRegionId(this.getRegionId()); + List volumeDetail = this.getVolumeDetail(convertModel); + if (!CollectionUtils.isEmpty(volumeDetail)) { + convertModel.setDiskDevices(volumeDetail); + } + } + return new BocloudResult(true, convertModel, "detail cloudServer success!"); + } catch (Exception e) { + logger.error("detail cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + public BocloudResult getStatusDetail(String instanceId, String serverStatus) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeInstancesRequest req = new DescribeInstancesRequest(); + req.setInstanceIds(new String[] { instanceId }); + DescribeInstancesResponse resp = client.DescribeInstances(req); + Instance[] instanceSet = resp.getInstanceSet(); + ServerModel convertModel = null; + if (null != instanceSet && instanceSet.length > 0) { + Instance instance = instanceSet[0]; + convertModel = convertor.convertModel(instance); + convertModel.setRegionId(this.getRegionId()); + if (!StringUtils.isEmpty(serverStatus)) { + convertModel.setStatus(serverStatus); + } + List volumeDetail = this.getVolumeDetail(convertModel); + if (null != volumeDetail) { + convertModel.setDiskDevices(volumeDetail); + } + } + return new BocloudResult(true, convertModel, "detail cloudServer success!"); + } catch (Exception e) { + logger.error("detail status cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, "detail status cloudServer error :{}" + e.getMessage()); + } + } + + private List getVolumeDetail(ServerModel convertModel) { + List result = null; + try { + TceVolumeProvider volume = new TceVolumeProvider(butler); + Integer count = 3; + while (count > 0) { + BocloudResult list = volume.list(convertModel.getInstanceId()); + List parseArray = JSONObject.parseArray(JSON.toJSONString(list.getData()), + VolumeModel.class); + if (parseArray.size() > 0) { + result = parseArray; + count = -1; + } else { + count--; + Thread.sleep(2000); + } + } + } catch (Exception e) { + logger.error("detail volumeStatus error :{}", e.getMessage()); + } + return result; + } + + @Override + public BocloudResult start(String instanceId) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + StartInstancesRequest req = new StartInstancesRequest(); + req.setInstanceIds(new String[] { instanceId }); + client.StartInstances(req); + return new BocloudResult(true, "start cloudServer success!"); + } catch (Exception e) { + logger.error("start cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult stop(String instanceId) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + StopInstancesRequest req = new StopInstancesRequest(); + req.setInstanceIds(new String[] { instanceId }); + client.StopInstances(req); + return new BocloudResult(true, "stop cloudServer success!"); + } catch (Exception e) { + logger.error("stop cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult reboot(String instanceId) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + RebootInstancesRequest req = new RebootInstancesRequest(); + req.setInstanceIds(new String[] { instanceId }); + client.RebootInstances(req); + return new BocloudResult(true, "reboot cloudServer success!"); + } catch (Exception e) { + logger.error("reboot cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult softReboot(String instanceId) { + return null; + } + + @Override + public BocloudResult pause(String instanceId) { + return null; + } + + @Override + public BocloudResult unPause(String instanceId) { + return null; + } + + @Override + public BocloudResult suspend(String instanceId) { + return null; + } + + @Override + public BocloudResult resume(String instanceId) { + return null; + } + + @Override + public BocloudResult joinSGroup(String instanceId, String group) { + try { + // 查询当前实例的安全组 + BocloudResult bocloudResult = this.detail(instanceId); + if (bocloudResult.isFailed()) { + return new BocloudResult(false, bocloudResult.getMessage(), "修改安全组失败"); + } + ServerModel modes = (ServerModel) bocloudResult.getData(); + List securityGroups = new ArrayList<>(modes.getSecurityGroups()); + // 加入安全组 + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ModifyInstancesAttributeRequest request = new ModifyInstancesAttributeRequest(); + request.setInstanceIds(new String[] { instanceId }); + securityGroups.add(group); + String[] strings = new String[securityGroups.size()]; + request.setSecurityGroups(securityGroups.toArray(strings)); + client.ModifyInstancesAttribute(request); + return new BocloudResult(true, "joinSGroup cloudServer success!"); + } catch (Exception e) { + logger.error("joinSGroup cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult leaveSGroup(String instanceId, String group) { + try { + // 查询当前实例的安全组 + BocloudResult bocloudResult = this.detail(instanceId); + if (bocloudResult.isFailed()) { + return new BocloudResult(false, bocloudResult.getMessage(), "当前实例不存在"); + } + ServerModel modes = (ServerModel) bocloudResult.getData(); + List asList = new ArrayList<>(modes.getSecurityGroups()); + // 移除安全组 + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ModifyInstancesAttributeRequest request = new ModifyInstancesAttributeRequest(); + request.setInstanceIds(new String[] { instanceId }); + asList.remove(group); + String[] strings = new String[asList.size()]; + request.setSecurityGroups(asList.toArray(strings)); + client.ModifyInstancesAttribute(request); + return new BocloudResult(true, "leaveSGroup cloudServer success!"); + } catch (Exception e) { + logger.error("leaveSGroup cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult snapshot(SnapshotModel snapshotModel) { + return null; + } + + @Override + public BocloudResult vncConsole(String vncType, String serverId) { + return null; + } + + @Override + public BocloudResult changePassword(String instanceId, String password) { + try { + TreeMap params = new TreeMap<>(); + params.put("InstanceIds.0", instanceId); + params.put("Password", password); + params.put("ForceStop", true); + params.put("Version", "2017-03-12"); + TceRestApiProvider tceRestApiProvider = new TceRestApiProvider(butler); + tceRestApiProvider.connection(TceEnum.CVM, TceActionEnum.ResetInstancesPassword, params); + Thread.sleep(8000); + return new BocloudResult(true, "修改密码成功!"); + } catch (Exception e) { + logger.error("changePassword cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult attachNetwork(ServerModel server) { + try { + VpcClient client = (VpcClient) this.getClient(TceEnum.VPC); + AssociateAddressRequest request = new AssociateAddressRequest(); + request.setInstanceId(server.getInstanceId()); + request.setAddressId(server.getPublicIps()); + client.AssociateAddress(request); + return new BocloudResult(true, "attachNetwork cloudServer success!"); + } catch (Exception e) { + logger.error("attachNetwork cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult detachNetwork(String instanceId, String portUuid) { + try { + VpcClient client = (VpcClient) this.getClient(TceEnum.VPC); + DisassociateAddressRequest request = new DisassociateAddressRequest(); + request.setAddressId(portUuid); + client.DisassociateAddress(request); + return new BocloudResult(true, "detachNetwork cloudServer success!"); + } catch (Exception e) { + logger.error("detachNetwork cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult resize(String instanceId, String flavorId) { + return null; + } + + @Override + public BocloudResult resize(String instanceId, String flavorId, Boolean forceStop) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ResetInstancesTypeRequest req = new ResetInstancesTypeRequest(); + req.setInstanceIds(new String[] { instanceId }); + req.setInstanceType(flavorId); + req.setForceStop(forceStop); + client.ResetInstancesType(req); + BocloudResult result = this.getStatusInstances(instanceId); + if (result.isFailed()) { + return result; + } + return new BocloudResult(true, result.getData(), "resize cloudServer success!"); + } catch (Exception e) { + logger.error("resize cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult confirmResize(String instanceId) { + return null; + } + + @Override + public BocloudResult revertResize(String instanceId) { + return null; + } + + @Override + public BocloudResult hotConfigEnable(String instanceId, Boolean cpuHotEnable, Boolean MemHotEnable) { + return null; + } + + @Override + public BocloudResult getTicket(String instanceId) { + return null; + } + + @Override + public BocloudResult createInResPool(ServerModel server) { + return null; + } + + @Override + public BocloudResult mountToolsInstaller(String instanceId) { + return null; + } + + @Override + public BocloudResult unmountToolsInstaller(String instanceId) { + return null; + } + + @Override + public BocloudResult upgradeToolsTask(String instanceId, String options) { + return null; + } + + @Override + public BocloudResult getNetCard(String instanceId) { + return null; + } + + @Override + public BocloudResult getVmIps(String instanceId) { + return null; + } + + @Override + public BocloudResult markAsTemplate(String instanceId) { + return null; + } + + @Override + public BocloudResult changeVspVmPasswd(String instanceId, String oldPasswd, String newPasswd) { + try { + TreeMap params = new TreeMap<>(); + params.put("InstanceIds.0", instanceId); + params.put("Password", newPasswd); + params.put("ForceStop", true); + params.put("Version", "2017-03-12"); + TceRestApiProvider tceRestApiProvider = new TceRestApiProvider(butler); + tceRestApiProvider.connection(TceEnum.CVM, TceActionEnum.ResetInstancesPassword, params); + Thread.sleep(8000); + return new BocloudResult(true, this.detail(instanceId), "修改密码成功!"); + } catch (Exception e) { + logger.error("changePassword cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + /** + * 虚拟机磁盘扩容 + */ + @Override + public BocloudResult diskExtend(String instanceId, String diskLabel, Integer extendSize) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ResizeInstanceDisksRequest request = new ResizeInstanceDisksRequest(); + request.setInstanceId(instanceId); + request.setForceStop(false); // 默认不强制关机 + DataDisk dataDisk = new DataDisk(); + dataDisk.setDiskSize(Integer.valueOf(extendSize)); + request.setDataDisks(new DataDisk[] { dataDisk }); + client.ResizeInstanceDisks(request); + return new BocloudResult(true, "diskExtend cloudServer success!"); + } catch (Exception e) { + logger.error("diskExtend cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult getMetric(String type) { + return null; + } + + @Override + public BocloudResult vmrcConsole(String instanceId) { + return null; + } + + @Override + public BocloudResult migrate(H3cMigrateModel model) { + return null; + } + + @Override + public BocloudResult list(String hostId) { + return null; + } + + @Override + public BocloudResult create(H3cServerModel arg0) { + return null; + } + + @Override + public BocloudResult getJnlpXml(Long arg0, String arg1) { + return null; + } + + @Override + public BocloudResult resetInstance(ServerModel serverModel) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ResetInstanceRequest req = new ResetInstanceRequest(); + req.setInstanceId(serverModel.getInstanceId()); + req.setImageId(serverModel.getImageUuid()); + // 登录方式 + LoginSettings loginSettings = new LoginSettings(); + String password = serverModel.getPassword(); + if (!StringUtils.isEmpty(password)) { + loginSettings.setPassword(password); + } + String keypairId = serverModel.getKeypairName(); + if (!StringUtils.isEmpty(keypairId)) { + loginSettings.setKeyIds(new String[] { keypairId }); + } + req.setLoginSettings(loginSettings); + client.ResetInstance(req); + return new BocloudResult(true, this.getInstancesByImage(serverModel.getInstanceId(), + serverModel.getImageUuid()).getData(), "resetInstance cloudServer success!"); + } catch (Exception e) { + logger.error("resetInstance cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + public BocloudResult getInstancesByImage(String instanceId, String imageId) { + BocloudResult result = new BocloudResult(false, "reset server data does not exist"); + try { + Long startTime = System.currentTimeMillis(); + Long endTime = System.currentTimeMillis(); + while (endTime - startTime < 5 * 60 * 1000) { + // 增加休眠减少轮询次数 + Thread.sleep(6000); + BocloudResult detail = this.detail(instanceId); + ServerModel serverModel = JSON.parseObject(JSON.toJSONString(detail.getData()), ServerModel.class); + if (null != serverModel && imageId.equals(serverModel.getImageUuid())) { + result = this.detail(instanceId); + break; + } + endTime = System.currentTimeMillis(); + } + } catch (Exception e) { + logger.error("reset server get status error: " + e.getMessage()); + result = new BocloudResult(false, "reset server get status error: " + e.getMessage()); + } + return result; + } + + @Override + public BocloudResult resetInternetMaxBandwidthOut(String instanceId, Integer internetMaxBandwidthOut) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ResetInstancesInternetMaxBandwidthRequest req = new ResetInstancesInternetMaxBandwidthRequest(); + req.setInstanceIds(new String[] { instanceId }); + InternetAccessible internetAccessible = new InternetAccessible(); + internetAccessible.setInternetMaxBandwidthOut(Integer.valueOf(internetMaxBandwidthOut)); + req.setInternetAccessible(internetAccessible); + client.ResetInstancesInternetMaxBandwidth(req); + return new BocloudResult(true, "broadband cloudServer success!"); + } catch (Exception e) { + logger.error("broadband cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult bindKeypair(ServerModel serverModel) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + AssociateInstancesKeyPairsRequest req = new AssociateInstancesKeyPairsRequest(); + req.setInstanceIds(serverModel.getInstanceIds()); + req.setKeyIds(serverModel.getKeypairIds()); + client.AssociateInstancesKeyPairs(req); + return new BocloudResult(true, "bindKeypair cloudServer succeess!"); + } catch (Exception e) { + logger.error("bindKeypair cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult unbindKeypair(ServerModel serverModel) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DisassociateInstancesKeyPairsRequest req = new DisassociateInstancesKeyPairsRequest(); + req.setInstanceIds(serverModel.getInstanceIds()); + req.setKeyIds(serverModel.getKeypairIds()); + client.DisassociateInstancesKeyPairs(req); + return new BocloudResult(true, "unbindKeypair cloudServer success!"); + } catch (Exception e) { + logger.error("unbindKeypair cloudServer error :{}", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult createImage(String instanceId, String imageName, List volumes) { + return null; + } + +} \ No newline at end of file diff --git a/src/main/java/com/bocloud/cmp/provider/compute/TceSnapshotProvider.java b/src/main/java/com/bocloud/cmp/provider/compute/TceSnapshotProvider.java new file mode 100644 index 0000000..f1da978 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/compute/TceSnapshotProvider.java @@ -0,0 +1,169 @@ +package com.bocloud.cmp.provider.compute; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.lang3.ObjectUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.SnapshotModel; +import com.bocloud.cmp.provider.TceProvider; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.cmp.tceconvertor.SnapshotConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; +import com.tencentcloudapi.cbs.v20170312.CbsClient; +import com.tencentcloudapi.cbs.v20170312.models.ApplySnapshotRequest; +import com.tencentcloudapi.cbs.v20170312.models.DeleteSnapshotsRequest; +import com.tencentcloudapi.cbs.v20170312.models.DescribeSnapshotsRequest; +import com.tencentcloudapi.cbs.v20170312.models.DescribeSnapshotsResponse; +import com.tencentcloudapi.cbs.v20170312.models.ModifySnapshotAttributeRequest; +import com.tencentcloudapi.cbs.v20170312.models.Snapshot; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceSnapshotProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceSnapshotProvider extends TceProvider implements SnapshotProvider { + + private static Logger logger = LoggerFactory.getLogger(TceSnapshotProvider.class); + + private BeanConvertor convertor = new SnapshotConvertor(); + + public TceSnapshotProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult list() { + try { + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + DescribeSnapshotsResponse response = client.DescribeSnapshots(new DescribeSnapshotsRequest()); + List models = convertor.convertList(Arrays.asList(response.getSnapshotSet())); + Optional.ofNullable(models).ifPresent(snapshotModels -> snapshotModels.stream().forEach(snapshotModel -> snapshotModel.setRegionId(this.getRegionId()))); + return new BocloudResult(true, models, "list snapshot success!"); + } catch (Exception e) { + logger.error("list snapshot error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult remove(SnapshotModel model) { + try { + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + DeleteSnapshotsRequest req = new DeleteSnapshotsRequest(); + req.setSnapshotIds(new String[]{model.getSnapshotUuid()}); + client.DeleteSnapshots(req); + return new BocloudResult(true, "remove snapshot success!"); + } catch (Exception e) { + logger.error("remove snapshot error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult detail(SnapshotModel model) { + try { + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + DescribeSnapshotsRequest req = new DescribeSnapshotsRequest(); + req.setSnapshotIds(new String[]{model.getSnapshotUuid()}); + DescribeSnapshotsResponse resp = client.DescribeSnapshots(req); + Snapshot[] snapshotSet = resp.getSnapshotSet(); + SnapshotModel convertModel = null; + if (null != snapshotSet && snapshotSet.length > 0) { + convertModel = convertor.convertModel(snapshotSet[0]); + convertModel.setRegionId(this.getRegionId()); + } + return new BocloudResult(true, convertModel, "detail snapshot success!"); + } catch (Exception e) { + logger.error("detail snapshot error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult modify(SnapshotModel model) { + try { + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + ModifySnapshotAttributeRequest request = new ModifySnapshotAttributeRequest(); + request.setSnapshotId(model.getSnapshotUuid()); + request.setSnapshotName(model.getName()); + client.ModifySnapshotAttribute(request); + return new BocloudResult(true, "modify snapshot success!"); + } catch (Exception e) { + logger.error("modify snapshot error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult revert(SnapshotModel model) { + try { + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + ApplySnapshotRequest request = new ApplySnapshotRequest(); + request.setDiskId(model.getVolumeUuid()); + request.setSnapshotId(model.getSnapshotUuid()); + client.ApplySnapshot(request); + return new BocloudResult(true, "revert snapshot success!"); + } catch (Exception e) { + logger.error("revert snapshot error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult removeByVolumeId(String volumeId) { + return null; + } + + @Override + public BocloudResult getSnapshot(String snapshotId) { + BocloudResult result = new BocloudResult(false, "data does not exist"); + SnapshotModel snapshotModel = new SnapshotModel(); + snapshotModel.setSnapshotUuid(snapshotId); + try { + Long startTime = System.currentTimeMillis(); + Long endTime = System.currentTimeMillis(); + while (endTime - startTime < 5 * 60 * 1000) { + //创建时间不确定,增加休眠减少轮询次数 + Thread.sleep(6000); + BocloudResult detail = this.detail(snapshotModel); + SnapshotModel model = JSONObject.parseObject(JSONObject.toJSONString(detail.getData()), SnapshotModel.class); + if (ObjectUtils.isEmpty(model)) { + logger.error("data does not exist :", snapshotId); + break; + } + if ("NORMAL".equalsIgnoreCase(model.getStatus()) || "AVAILABLE".equalsIgnoreCase(model.getStatus())) { + result = this.detail(snapshotModel); + break; + } + endTime = System.currentTimeMillis(); + } + } catch (Exception e) { + logger.error("create snapshot get status error: " + e.getMessage()); + result = new BocloudResult(false, "create snapshot get status error: " + e.getMessage()); + } + return result; + } + + @Override + public BocloudResult getAvaliableSnap(String snapshotId) { + return null; + } + + @Override + public BocloudResult list(Long arg0) { + return null; + } + +} diff --git a/src/main/java/com/bocloud/cmp/provider/network/TceSecuGroupProvider.java b/src/main/java/com/bocloud/cmp/provider/network/TceSecuGroupProvider.java new file mode 100644 index 0000000..8966c80 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/network/TceSecuGroupProvider.java @@ -0,0 +1,106 @@ +package com.bocloud.cmp.provider.network; + +import java.util.TreeMap; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceActionEnum; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.SecurityGroupModel; +import com.bocloud.cmp.provider.TceRestApiProvider; +import com.bocloud.cmp.provider.convertor.BeanJsonConvertor; +import com.bocloud.cmp.tceconvertor.SecurityGroupConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceSecuGroupProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceSecuGroupProvider extends TceRestApiProvider implements SecurityGroupProvider { + + private static Logger logger = LoggerFactory.getLogger(TceSecuGroupProvider.class); + + private BeanJsonConvertor convertor = new SecurityGroupConvertor(); + + public TceSecuGroupProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult list() { + TreeMap params = new TreeMap<>(); + JSONObject object = this.connection(TceEnum.DFW, TceActionEnum.LIST_SECURITY_GROUP, params); + if (this.verify(object)) { + return new BocloudResult(true, convertor.convertList(object.getJSONArray("data")), "list securityGroup success!"); + } else { + logger.error("list securityGroup error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult create(SecurityGroupModel group) { + TreeMap params = new TreeMap<>(); + params.put("sgName", group.getName()); + String remark = group.getRemark(); + if (StringUtils.isEmpty(remark)) { + remark = ""; + } + params.put("sgRemark", remark); + JSONObject object = this.connection(TceEnum.DFW, TceActionEnum.CREATE_SECURITY_GROUP, params); + if (this.verify(object)) { + JSONObject jsonObject = object.getJSONObject("data"); + // 因为新创建的安全组没有拿到创建时间 所以查询一个detail + SecurityGroupModel groupModel = convertor + .convertModel((JSONObject) this.detail(jsonObject.getString("sgId")).getData()); + groupModel.setRegionId(this.getRegionId()); + return new BocloudResult(true, groupModel, "create securityGroup success!"); + } else { + logger.error("create securityGroup error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult remove(String sgId) { + TreeMap params = new TreeMap<>(); + params.put("sgId", sgId); + JSONObject object = this.connection(TceEnum.DFW, TceActionEnum.REMOVE_SECURITY_GROUP, params); + if (this.verify(object)) { + return new BocloudResult(true, "remove securityGroup success!"); + } else { + logger.error("remove securityGroup error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + + } + + @Override + public BocloudResult detail(String sgId) { + TreeMap params = new TreeMap<>(); + params.put("sgId", sgId); + JSONObject object = this.connection(TceEnum.DFW, TceActionEnum.LIST_SECURITY_GROUP, params); + if (this.verify(object)) { + JSONArray jsonArray = object.getJSONArray("data"); + return new BocloudResult(true, jsonArray.get(0), "query securityGroup success!"); + } else { + logger.error("query securityGroup error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult modify(SecurityGroupModel model) { + return null; + } +} diff --git a/src/main/java/com/bocloud/cmp/provider/network/TceSecuGroupRuleProvider.java b/src/main/java/com/bocloud/cmp/provider/network/TceSecuGroupRuleProvider.java new file mode 100644 index 0000000..bf9aa56 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/network/TceSecuGroupRuleProvider.java @@ -0,0 +1,168 @@ +package com.bocloud.cmp.provider.network; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeMap; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceActionEnum; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.SecurityGroupRuleModel; +import com.bocloud.cmp.provider.TceRestApiProvider; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceSecuGroupRuleProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceSecuGroupRuleProvider extends TceRestApiProvider implements SecurityGroupRuleProvider { + + private static Logger logger = LoggerFactory.getLogger(TceSecuGroupRuleProvider.class); + + public TceSecuGroupRuleProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult list(String secuId) { + TreeMap params = new TreeMap<>(); + params.put("sgId", secuId); + JSONObject object = this.connection(TceEnum.DFW, TceActionEnum.LIST_SECURITY_GROUP_RULE, params); + if (this.verify(object)) { + List list = convertModel(object.getJSONObject("data"), secuId); + return new BocloudResult(true, list, "list securityGroupRule success!"); + } else { + logger.error("list securityGroupRule error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult create(SecurityGroupRuleModel model) { + TreeMap params = new TreeMap<>(); + params.put("sgId", model.getGroupUuid()); + params.put("direction", model.getDirection()); + params.put("index", model.getSgrIndex()); + String action = model.getAction(); + if (StringUtils.isEmpty(action)) { + action = "ACCEPT"; // ACCEPT允许 DROPzuzh + } + params.put("policys.0.action", action); + params.put("policys.0.ipProtocol", model.getProtocol()); + params.put("policys.0.cidrIp", model.getRemoteIpPrefix()); + params.put("policys.0.desc", model.getRemark()); + if (!"icmp".equalsIgnoreCase(model.getProtocol())) { + Integer portMax = model.getPortMax(); + Integer portMin = model.getPortMin(); + if (null == portMax || null == portMin) { + return new BocloudResult(false, "参数必要参数缺失!"); + } + if (portMax.equals(portMin)) { + params.put("policys.0.portRange", portMax + ""); + } else { + params.put("policys.0.portRange", portMin + "-" + portMax); + } + } + JSONObject object = this.connection(TceEnum.DFW, TceActionEnum.CREATE_SECURITY_GROUP_RULE, params); + if (this.verify(object)) { + model.setAction(model.getAction() == null ? "ACCEPT" : model.getAction()); + return new BocloudResult(true, model, "create securityGroupRule success!"); + } else { + logger.error("create securityGroupRule error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult remove(String ruleId) { + return null; + } + + @Override + public BocloudResult remove(SecurityGroupRuleModel model) { + TreeMap params = new TreeMap<>(); + params.put("sgId", model.getGroupUuid()); + params.put("direction", model.getDirection()); + params.put("indexes.0", model.getSgrIndex()); + JSONObject object = this.connection(TceEnum.DFW, TceActionEnum.REMOVE_SECURITY_GROUP_RULE, params); + if (this.verify(object)) { + return new BocloudResult(true, "remove securityGroupRule success!"); + } else { + logger.error("remove securityGroupRule error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + public List convertModel(JSONObject object, String groupUuid) { + List securityGroupRuleModels = new ArrayList<>(); + JSONArray ingressArray = object.getJSONArray("ingress"); + JSONArray egressArray = object.getJSONArray("egress"); + if (ingressArray.size() == 0 && egressArray.size() == 0) { + return securityGroupRuleModels; + } + for (int i = 0; i < ingressArray.size(); i++) { + JSONObject modelObject = ingressArray.getJSONObject(i); + SecurityGroupRuleModel model = new SecurityGroupRuleModel(); + model.setGroupUuid(groupUuid); + model.setSgrIndex(modelObject.getInteger("index")); + model.setRemoteIpPrefix(modelObject.getString("cidrIp")); + model.setRemark(modelObject.getString("desc")); + model.setProtocol(modelObject.getString("ipProtocol").toUpperCase()); + if (!modelObject.getString("portRange").equalsIgnoreCase("ALL")) { + String port = modelObject.getString("portRange"); + if (null != port && port.contains(",")) { + // 目前不支持 不连续的端口 + } else if (null != port && port.contains("-")) { + String[] split = port.split("-"); + model.setPortMin(Integer.parseInt(split[0])); + model.setPortMax(Integer.parseInt(split[1])); + } else { + model.setPortMin(Integer.parseInt(port)); + model.setPortMax(Integer.parseInt(port)); + } + } + model.setDirection("ingress"); + model.setAction(modelObject.getString("action")); + securityGroupRuleModels.add(model); + } + + for (int i = 0; i < egressArray.size(); i++) { + JSONObject modelObject = egressArray.getJSONObject(i); + SecurityGroupRuleModel model = new SecurityGroupRuleModel(); + model.setGroupUuid(groupUuid); + model.setSgrIndex(modelObject.getInteger("index")); + model.setRemoteIpPrefix(modelObject.getString("cidrIp")); + model.setRemark(modelObject.getString("desc")); + model.setProtocol(modelObject.getString("ipProtocol").toUpperCase()); + if (!modelObject.getString("portRange").equalsIgnoreCase("ALL")) { + String port = modelObject.getString("portRange"); + if (null != port && port.contains(",")) { + // 目前不支持 不连续的端口 + } else if (null != port && port.contains("-")) { + String[] split = port.split("-"); + model.setPortMin(Integer.parseInt(split[0])); + model.setPortMax(Integer.parseInt(split[1])); + } else { + model.setPortMin(Integer.parseInt(port)); + model.setPortMax(Integer.parseInt(port)); + } + } + model.setDirection("egress"); + model.setAction(modelObject.getString("action")); + securityGroupRuleModels.add(model); + } + return securityGroupRuleModels; + } + +} diff --git a/src/main/java/com/bocloud/cmp/provider/network/TceSubnetProvider.java b/src/main/java/com/bocloud/cmp/provider/network/TceSubnetProvider.java new file mode 100644 index 0000000..56dd884 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/network/TceSubnetProvider.java @@ -0,0 +1,118 @@ +package com.bocloud.cmp.provider.network; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceActionEnum; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.SubnetModel; +import com.bocloud.cmp.provider.TceRestApiProvider; +import com.bocloud.cmp.provider.convertor.BeanJsonConvertor; +import com.bocloud.cmp.tceconvertor.SubnetConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceSubnetProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceSubnetProvider extends TceRestApiProvider implements SubnetProvider { + + private static Logger logger = LoggerFactory.getLogger(TceSubnetProvider.class); + + private BeanJsonConvertor convertor = new SubnetConvertor(); + + public TceSubnetProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult list() { + Integer offset = 0; + TreeMap params = new TreeMap<>(); + params.put("limit", LIMIT); + List list = new ArrayList<>(); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.LIST_SUBNET, params); + if (this.verify(object)) { + list.addAll(convertor.convertList(object.getJSONArray("data"))); + while (object.getInteger("totalCount") >= offset + LIMIT) { + params.put("offset", (offset += LIMIT)); + object = this.connection(TceEnum.VPC, TceActionEnum.LIST_SUBNET, params); + list.addAll(convertor.convertList(object.getJSONArray("data"))); + } + return new BocloudResult(true, list, "list subnet success!"); + } else { + logger.error("list subnet error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult create(SubnetModel subnet) { + TreeMap params = new TreeMap<>(); + params.put("vpcId", subnet.getVpcUuid()); + params.put("subnetSet." + subscript + ".subnetName", subnet.getName()); + params.put("subnetSet." + subscript + ".cidrBlock", subnet.getCidr()); + params.put("subnetSet." + subscript + ".zoneId", subnet.getZoneNum()); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.CREATE_SUBNET, params); + if (this.verify(object)) { + SubnetModel convertModel = convertor.convertModel(object.getJSONArray("subnetSet").getJSONObject(0)); + convertModel.setRegionId(this.getRegionId()); + convertModel.setZone(subnet.getZone()); + return new BocloudResult(true, convertModel, "create subnet success!"); + } else { + logger.error("create subnet error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult modify(SubnetModel subnet) { + return null; + } + + @Override + public BocloudResult remove(String subnetId) { + return null; + } + + @Override + public BocloudResult detail(String subnetId) { + TreeMap params = new TreeMap<>(); + params.put("limit", LIMIT); + params.put("subnetId", subnetId); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.LIST_SUBNET, params); + if (this.verify(object)) { + JSONArray jsonArray = object.getJSONArray("data"); + return new BocloudResult(true, convertor.convertModel(jsonArray.getJSONObject(0)), "list subnet success!"); + } else { + logger.error("list subnet error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult remove(SubnetModel subnet) { + TreeMap params = new TreeMap<>(); + params.put("vpcId", subnet.getVpcUuid()); + params.put("subnetId", subnet.getSubnetUuid()); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.REMOVE_SUBNET, params); + if (this.verify(object)) { + return new BocloudResult(true, "remove subnet success!"); + } else { + logger.error("remove subnet error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } +} diff --git a/src/main/java/com/bocloud/cmp/provider/network/TceVpcProvider.java b/src/main/java/com/bocloud/cmp/provider/network/TceVpcProvider.java new file mode 100644 index 0000000..3d74e60 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/network/TceVpcProvider.java @@ -0,0 +1,123 @@ +package com.bocloud.cmp.provider.network; + +import java.util.ArrayList; +import java.util.List; +import java.util.TreeMap; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.common.enums.TceActionEnum; +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.VpcModel; +import com.bocloud.cmp.provider.TceRestApiProvider; +import com.bocloud.cmp.provider.convertor.BeanJsonConvertor; +import com.bocloud.cmp.tceconvertor.VpcConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceVpcProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceVpcProvider extends TceRestApiProvider implements VpcProvider { + + private static Logger logger = LoggerFactory.getLogger(TceVpcProvider.class); + + private BeanJsonConvertor convertor = new VpcConvertor(); + + public TceVpcProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult create(VpcModel model) { + TreeMap params = new TreeMap<>(); + params.put("vpcName", model.getName()); + params.put("cidrBlock", model.getCidr()); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.CREATE_VPC, params); + if (this.verify(object)) { + model.setVpcId(object.getString("uniqVpcId")); + model.setDefaultVpc(false); + model.setStatus("ACTIVE"); + return new BocloudResult(true, model, "create vpc success!"); + } else { + logger.error("create vpc error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult remove(String vpcId) { + TreeMap params = new TreeMap<>(); + params.put("vpcId", vpcId); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.REMOVE_VPC, params); + if (this.verify(object)) { + return new BocloudResult(true, "remove vpc success!"); + } else { + logger.error("remove vpc error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult list() { + Integer offset = 0; + TreeMap params = new TreeMap<>(); + params.put("limit", LIMIT); + List list = new ArrayList<>(); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.LIST_VPC, params); + if (this.verify(object)) { + list.addAll(convertor.convertList(object.getJSONArray("data"))); + while (object.getInteger("totalCount") >= offset + LIMIT) { + params.put("offset", (offset += LIMIT)); + object = this.connection(TceEnum.VPC, TceActionEnum.LIST_VPC, params); + list.addAll(convertor.convertList(object.getJSONArray("data"))); + } + return new BocloudResult(true, list, "list vpc success!"); + } else { + logger.error("list vpc error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + + @Override + public BocloudResult detail(String vpcId, String regionId) { + try { + TreeMap params = new TreeMap<>(); + params.put("vpcId", vpcId); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.LIST_VPC, params); + List vpcModels = new ArrayList<>(); + if (this.verify(object)) { + vpcModels = convertor.convertList(object.getJSONArray("data")); + } + VpcModel vpcModel = vpcModels.get(0); + vpcModel.setRegionId(regionId); + return new BocloudResult(true, vpcModel, "detail vpc success!"); + } catch (Exception e) { + logger.error("detail vpc error :", e); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult update(VpcModel model) { + TreeMap params = new TreeMap<>(); + params.put("vpcId", model.getVpcId()); + params.put("vpcName", model.getName()); + JSONObject object = this.connection(TceEnum.VPC, TceActionEnum.MODIFY_VPC, params); + if (this.verify(object)) { + return this.detail(model.getVpcId(), model.getRegionId()); + } else { + logger.error("modify vpc error : " + object.getString(MESSAGE)); + return new BocloudResult(false, object.getString(MESSAGE)); + } + } + +} diff --git a/src/main/java/com/bocloud/cmp/provider/security/TceKeypairProvider.java b/src/main/java/com/bocloud/cmp/provider/security/TceKeypairProvider.java new file mode 100644 index 0000000..999cc1a --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/security/TceKeypairProvider.java @@ -0,0 +1,135 @@ +package com.bocloud.cmp.provider.security; + +import java.util.Arrays; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.KeypairModel; +import com.bocloud.cmp.provider.TceProvider; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.cmp.tceconvertor.KeypairConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; +import com.tencentcloudapi.cvm.v20170312.CvmClient; +import com.tencentcloudapi.cvm.v20170312.models.CreateKeyPairRequest; +import com.tencentcloudapi.cvm.v20170312.models.CreateKeyPairResponse; +import com.tencentcloudapi.cvm.v20170312.models.DeleteKeyPairsRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeKeyPairsRequest; +import com.tencentcloudapi.cvm.v20170312.models.DescribeKeyPairsResponse; +import com.tencentcloudapi.cvm.v20170312.models.ImportKeyPairRequest; +import com.tencentcloudapi.cvm.v20170312.models.ImportKeyPairResponse; +import com.tencentcloudapi.cvm.v20170312.models.KeyPair; +import com.tencentcloudapi.cvm.v20170312.models.ModifyKeyPairAttributeRequest; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: TceKeypairProvider + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +@Provider("bocloud.cmp.tce") +public class TceKeypairProvider extends TceProvider implements KeypairProvider { + + private static Logger logger = LoggerFactory.getLogger(TceKeypairProvider.class); + + private BeanConvertor convertor = new KeypairConvertor(); + + public TceKeypairProvider(Butler butler) { + super(butler); + } + + @Override + public BocloudResult list() { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeKeyPairsResponse response = client.DescribeKeyPairs(new DescribeKeyPairsRequest()); + return new BocloudResult(true, convertor.convertList(Arrays.asList(response.getKeyPairSet())), + "list keypair success!"); + } catch (Exception e) { + logger.error("list keypair error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult detail(String keypairName) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DescribeKeyPairsRequest request = new DescribeKeyPairsRequest(); + request.setKeyIds(new String[] { keypairName }); + DescribeKeyPairsResponse response = client.DescribeKeyPairs(request); + KeyPair[] keyPairs = response.getKeyPairSet(); + KeyPair key = null; + if (null != keyPairs && keyPairs.length > 0) { + key = keyPairs[0]; + } + return new BocloudResult(true, convertor.convertModel(key), "detail keypair success!"); + } catch (Exception e) { + logger.error("detail keypair error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult create(String keypairName, String publicKey) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + if (!StringUtils.isEmpty(publicKey)) { + ImportKeyPairRequest request = new ImportKeyPairRequest(); + request.setKeyName(keypairName); + request.setPublicKey(publicKey); + if (!StringUtils.isEmpty(this.getProjectId())) { + request.setProjectId(Integer.valueOf(this.getProjectId())); + } + ImportKeyPairResponse response = client.ImportKeyPair(request); + return this.detail(response.getKeyId()); + } else { + CreateKeyPairRequest req = new CreateKeyPairRequest(); + req.setKeyName(keypairName); + if (!StringUtils.isEmpty(this.getProjectId())) { + req.setProjectId(Integer.valueOf(this.getProjectId())); + } + CreateKeyPairResponse resp = client.CreateKeyPair(req); + return new BocloudResult(true, convertor.convertModel(resp.getKeyPair()), "create keypair success!"); + } + } catch (Exception e) { + logger.error("create keypair error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult delete(String keypairName) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + DeleteKeyPairsRequest request = new DeleteKeyPairsRequest(); + request.setKeyIds(new String[] { keypairName }); + client.DeleteKeyPairs(request); + return new BocloudResult(true, "delete keypair success!"); + } catch (Exception e) { + logger.error("delete keypair error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult modify(KeypairModel model) { + try { + CvmClient client = (CvmClient) this.getClient(TceEnum.CVM); + ModifyKeyPairAttributeRequest request = new ModifyKeyPairAttributeRequest(); + request.setKeyName(model.getName()); + request.setKeyId(model.getKeyId()); + client.ModifyKeyPairAttribute(request); + return new BocloudResult(true, "modify keypair success!"); + } catch (Exception e) { + logger.error("modify keypair error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + +} diff --git a/src/main/java/com/bocloud/cmp/provider/storage/TceVolumeProvider.java b/src/main/java/com/bocloud/cmp/provider/storage/TceVolumeProvider.java new file mode 100644 index 0000000..22d3b6e --- /dev/null +++ b/src/main/java/com/bocloud/cmp/provider/storage/TceVolumeProvider.java @@ -0,0 +1,277 @@ +package com.bocloud.cmp.provider.storage; + +import java.util.Arrays; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.bocloud.cmp.common.enums.TceEnum; +import com.bocloud.cmp.model.Butler; +import com.bocloud.cmp.model.ImageModel; +import com.bocloud.cmp.model.SnapshotModel; +import com.bocloud.cmp.model.VolumeModel; +import com.bocloud.cmp.model.h3c.H3cVolumeModel; +import com.bocloud.cmp.provider.TceProvider; +import com.bocloud.cmp.provider.compute.TceSnapshotProvider; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.cmp.tceconvertor.VolumeConvertor; +import com.bocloud.common.annotations.Provider; +import com.bocloud.common.model.BocloudResult; +import com.tencentcloudapi.cbs.v20170312.CbsClient; +import com.tencentcloudapi.cbs.v20170312.models.AttachDisksRequest; +import com.tencentcloudapi.cbs.v20170312.models.AttachDisksResponse; +import com.tencentcloudapi.cbs.v20170312.models.CreateDisksRequest; +import com.tencentcloudapi.cbs.v20170312.models.CreateDisksResponse; +import com.tencentcloudapi.cbs.v20170312.models.CreateSnapshotRequest; +import com.tencentcloudapi.cbs.v20170312.models.CreateSnapshotResponse; +import com.tencentcloudapi.cbs.v20170312.models.DescribeDisksRequest; +import com.tencentcloudapi.cbs.v20170312.models.DescribeDisksResponse; +import com.tencentcloudapi.cbs.v20170312.models.DetachDisksRequest; +import com.tencentcloudapi.cbs.v20170312.models.Disk; +import com.tencentcloudapi.cbs.v20170312.models.DiskChargePrepaid; +import com.tencentcloudapi.cbs.v20170312.models.Filter; +import com.tencentcloudapi.cbs.v20170312.models.ModifyDiskAttributesRequest; +import com.tencentcloudapi.cbs.v20170312.models.Placement; +import com.tencentcloudapi.cbs.v20170312.models.ResizeDiskRequest; +import com.tencentcloudapi.cbs.v20170312.models.TerminateDisksRequest; + +/** + * 卷操作类 + * + * @author ymh + * @时间 2018年11月15日 + */ +@Provider("bocloud.cmp.tce") +public class TceVolumeProvider extends TceProvider implements VolumeProvider { + + private static Logger logger = LoggerFactory.getLogger(TceVolumeProvider.class); + + private BeanConvertor convertor = new VolumeConvertor(); + + private Butler butler; + + public TceVolumeProvider(Butler butler) { + super(butler); + this.butler = butler; + } + + @Override + public BocloudResult list() { + try { + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + DescribeDisksResponse response = client.DescribeDisks(new DescribeDisksRequest()); + return new BocloudResult(true, convertor.convertList(Arrays.asList(response.getDiskSet())), + "list disk success!"); + } catch (Exception e) { + logger.error("list disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + public BocloudResult list(String instanceId) { + try { + DescribeDisksRequest req = new DescribeDisksRequest(); + Filter f = new Filter(); + f.setName("instance-id"); + f.setValues(new String[] { instanceId }); + Filter[] filters = new Filter[] { f }; + req.setFilters(filters); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + DescribeDisksResponse resp = client.DescribeDisks(req); + Disk[] diskSet = resp.getDiskSet(); + return new BocloudResult(true, convertor.convertList(Arrays.asList(diskSet)), "list disk success!"); + } catch (Exception e) { + logger.error("list disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult create(VolumeModel volume) { + try { + CreateDisksRequest req = new CreateDisksRequest(); + // CLOUD_BASIC:表示普通云硬盘 + // CLOUD_PREMIUM:表示高性能云硬盘 + // CLOUD_SSD:表示SSD云硬盘。 + req.setDiskType(volume.getType()); + // PREPAID:预付费,即包年包月 + // POSTPAID_BY_HOUR:按小时后付费 + String diskChargeType = volume.getDiskChargeType(); + if (null == diskChargeType || "".equals(diskChargeType)) { + diskChargeType = "POSTPAID_BY_HOUR"; + } + req.setDiskChargeType(diskChargeType); // 按小时计费 + volume.setDiskChargeType(diskChargeType); + if ("PREPAID".equalsIgnoreCase(diskChargeType)) { + DiskChargePrepaid diskChargePrepaid = new DiskChargePrepaid(); + Integer period = volume.getPeriod(); + if (null == period || period <= 0) { + period = 1; + } + diskChargePrepaid.setPeriod(Integer.valueOf(period)); + req.setDiskChargePrepaid(diskChargePrepaid); + } + Placement placement = new Placement(); + String proId = this.getProjectId(); + if (null != proId && !"".equals(proId)) { + placement.setProjectId(Integer.valueOf(this.getProjectId())); + } + placement.setZone(volume.getZone()); + req.setPlacement(placement); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + if (null != volume.getSourceSnapshotId() && !"".equals(volume.getSourceSnapshotId())) { + req.setSnapshotId(volume.getSourceSnapshotId()); + } + req.setDiskSize(Integer.valueOf(volume.getSize())); + req.setDiskName(volume.getName()); + CreateDisksResponse createDisks = client.CreateDisks(req); + volume.setVolumeUuid(createDisks.getDiskIdSet()[0]); + volume.setRegionId(this.getRegionId()); + return new BocloudResult(true, volume, "create disk success!"); + } catch (Exception e) { + logger.error("create disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult modify(VolumeModel volume) { + try { + ModifyDiskAttributesRequest req = new ModifyDiskAttributesRequest(); + req.setDiskName(volume.getName()); + req.setDeleteWithInstance(volume.getDeleteWithInstance()); + req.setDiskIds(new String[] { volume.getVolumeUuid() }); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + client.ModifyDiskAttributes(req); + return new BocloudResult(true, "modify disk success!"); + } catch (Exception e) { + logger.error("modify disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult remove(String volumeId) { + try { + TerminateDisksRequest req = new TerminateDisksRequest(); + req.setDiskIds(new String[] { volumeId }); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + client.TerminateDisks(req); + return new BocloudResult(true, "remove disk success!"); + } catch (Exception e) { + logger.error("remove disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult detail(String volumeId) { + try { + DescribeDisksRequest req = new DescribeDisksRequest(); + req.setDiskIds(new String[] { volumeId }); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + DescribeDisksResponse resp = client.DescribeDisks(req); + Disk[] diskSet = resp.getDiskSet(); + VolumeModel volumeModel = convertor.convertModel(diskSet[0]); + volumeModel.setRegionId(this.getRegionId()); + return new BocloudResult(true, volumeModel, "detail disk success!"); + } catch (Exception e) { + logger.error("detail disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult snapshot(SnapshotModel snapshotModel) { + try { + CreateSnapshotRequest req = new CreateSnapshotRequest(); + req.setDiskId(snapshotModel.getVolumeUuid()); + req.setSnapshotName(snapshotModel.getName()); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + CreateSnapshotResponse resp = client.CreateSnapshot(req); + return new BocloudResult(true, this.snapshotDetail(resp.getSnapshotId()).getData(), + "create snapshot success!"); + } catch (Exception e) { + logger.error("create snapshot error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + private BocloudResult snapshotDetail(String snapshotId) { + TceSnapshotProvider provider = new TceSnapshotProvider(butler); + SnapshotModel model = new SnapshotModel(); + model.setSnapshotUuid(snapshotId); + BocloudResult detail = provider.detail(model); + return detail; + } + + @Override + public BocloudResult attach(String serverId, String volumeId) { + try { + AttachDisksRequest req = new AttachDisksRequest(); + req.setDiskIds(new String[] { volumeId }); + req.setInstanceId(serverId); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + AttachDisksResponse response = client.AttachDisks(req); + return new BocloudResult(true, response.getRequestId(), "attach disk success!"); + } catch (Exception e) { + logger.error("attach disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult attach(String serverId, String mountpoint, String volumeId) { + return null; + } + + @Override + public BocloudResult detach(String serverId, String volumeId) { + try { + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + DetachDisksRequest req = new DetachDisksRequest(); + req.setDiskIds(new String[] { volumeId }); + client.DetachDisks(req); + return new BocloudResult(true, "detach disk success!"); + } catch (Exception e) { + logger.error("detach disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult resetStatus(String volumeId, String status) { + return null; + } + + @Override + public BocloudResult uploadToImage(String volumeId, ImageModel imageModel) { + return null; + } + + @Override + public BocloudResult extend(String volumeId, Integer newSize) { + try { + ResizeDiskRequest req = new ResizeDiskRequest(); + req.setDiskId(volumeId); + req.setDiskSize(Integer.valueOf(newSize)); + CbsClient client = (CbsClient) this.getClient(TceEnum.CBS); + client.ResizeDisk(req); + return new BocloudResult(true, "extend disk success!"); + } catch (Exception e) { + logger.error("extend disk error :", e.getMessage()); + return new BocloudResult(false, e.getMessage()); + } + } + + @Override + public BocloudResult list(String hostId, String storagePoolName) { + return null; + } + + @Override + public BocloudResult remove(H3cVolumeModel arg0) { + return null; + } + +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/FlavorConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/FlavorConvertor.java new file mode 100644 index 0000000..b715199 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/FlavorConvertor.java @@ -0,0 +1,48 @@ +package com.bocloud.cmp.tceconvertor; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.bocloud.cmp.model.FlavorModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.tencentcloudapi.cvm.v20170312.models.InstanceTypeConfig; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: FlavorConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:53 + */ +public class FlavorConvertor implements BeanConvertor { + + @Override + public List convertList(List objects) { + List regionModels = new ArrayList(); + for (InstanceTypeConfig object : objects) { + String zone = object.getZone(); + if (StringUtils.isEmpty(zone)) { + continue; + } + regionModels.add(convertModel(object)); + } + return regionModels; + } + + @Override + public FlavorModel convertModel(InstanceTypeConfig info) { + FlavorModel model = new FlavorModel(); + model.setCpu(info.getCPU().intValue()); + model.setMemory(BigDecimal.valueOf(info.getMemory())); + model.setName(info.getInstanceType()); + model.setFamily(info.getInstanceFamily()); + model.setFlavorUuid(info.getInstanceType()); + model.setZone(info.getZone()); + model.setStatus("SELL"); + model.setInstanceChargeType("POSTPAID_BY_HOUR"); // 私有云全部为按量计费 + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/ImageConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/ImageConvertor.java new file mode 100644 index 0000000..2fdd14d --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/ImageConvertor.java @@ -0,0 +1,68 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import com.bocloud.cmp.model.ImageModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.tencentcloudapi.cvm.v20170312.models.Image; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: ImageConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class ImageConvertor implements BeanConvertor { + + @Override + public List convertList(List objects) { + List imageModels = new ArrayList(); + for (Image object : objects) { + imageModels.add(convertModel(object)); + } + return imageModels; + } + + @Override + public ImageModel convertModel(Image image) { + ImageModel model = new ImageModel(); + model.setImageUuid(image.getImageId()); + model.setName(image.getImageName()); + if (image.getImageType().equalsIgnoreCase("PUBLIC_IMAGE")) { + model.setImageType("PUBLIC"); + } else if (image.getImageType().equalsIgnoreCase("PRIVATE_IMAGE")) { + model.setImageType("PRIVATE"); + } else if (image.getImageType().equalsIgnoreCase("SHARED_IMAGE")) { + model.setImageType("SHARED"); + } else { + model.setImageType(image.getImageType()); + } + model.setOsName(image.getOsName()); + String platform = image.getPlatform(); + model.setOsType(platform); + if (null != platform && "Windows".equals(platform)) { + model.setOsCategory("Windows"); + } else { + model.setOsCategory("Linux"); + } + model.setRemark(image.getImageDescription()); + // 该代码因为腾讯环境数据异常,有条镜像大小为几千万G造成同步失败。 + if (image.getImageSize() > (10 * 1000)) { + model.setSize(Double.valueOf(image.getImageSize() / (10 * 1000))); + model.setMinDisk(Long.parseLong(image.getImageSize() / (10 * 1000) + "")); + } else { + model.setSize(Double.valueOf(image.getImageSize())); + model.setMinDisk(Long.parseLong(image.getImageSize() + "")); + } + model.setArchitecture(image.getArchitecture()); + String imageState = image.getImageState(); + if ("NORMAL".equals(imageState)) { + model.setStatus("ACTIVE"); + } else { + model.setStatus(imageState == null ? null : imageState.toUpperCase()); + } + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/KeypairConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/KeypairConvertor.java new file mode 100644 index 0000000..9bff8bf --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/KeypairConvertor.java @@ -0,0 +1,45 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.bocloud.cmp.model.KeypairModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.common.utils.DateTools; +import com.tencentcloudapi.cvm.v20170312.models.KeyPair; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: KeypairConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class KeypairConvertor implements BeanConvertor { + + @Override + public List convertList(List objects) { + List regionModels = new ArrayList(); + for (KeyPair object : objects) { + regionModels.add(convertModel(object)); + } + return regionModels; + } + + @Override + public KeypairModel convertModel(KeyPair info) { + KeypairModel model = new KeypairModel(); + model.setName(info.getKeyName()); + model.setPublicKey(info.getPublicKey()); + model.setPrivateKey(info.getPrivateKey()); + model.setFingerprint(info.getKeyId()); + model.setRemark(info.getDescription()); + String createdTime = info.getCreatedTime(); + if (!StringUtils.isEmpty(createdTime)) { + model.setGmtCreate(DateTools.transfer("yyyy-MM-dd'T'HH:mm:ssZ", info.getCreatedTime(), "Z")); + } + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/RegionConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/RegionConvertor.java new file mode 100644 index 0000000..a126716 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/RegionConvertor.java @@ -0,0 +1,42 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.bocloud.cmp.model.RegionModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.tencentcloudapi.cvm.v20170312.models.RegionInfo; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: RegionConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class RegionConvertor implements BeanConvertor { + + // 腾讯无法使用ap-guangzhou-open地域操作资源 华东地区(上海金融) 华南地区(深圳金融) 金融区域需特殊处理 + private static String[] EXCLUDE = {"ap-guangzhou-open", "ap-shanghai-fsi", "ap-shenzhen-fsi"}; + + @Override + public List convertList(List objects) { + List regionModels = new ArrayList(); + for (RegionInfo object : objects) { + if (!Arrays.asList(EXCLUDE).contains(object.getRegion())) { + regionModels.add(convertModel(object)); + } + } + return regionModels; + } + + @Override + public RegionModel convertModel(RegionInfo info) { + RegionModel model = new RegionModel(); + model.setCode(info.getRegion()); + model.setName(info.getRegionName()); + model.setRegionId(info.getRegion()); + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/SecurityGroupConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/SecurityGroupConvertor.java new file mode 100644 index 0000000..48f6c2b --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/SecurityGroupConvertor.java @@ -0,0 +1,48 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.model.SecurityGroupModel; +import com.bocloud.cmp.provider.convertor.BeanJsonConvertor; +import com.bocloud.common.utils.DateTools; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: SecurityGroupConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class SecurityGroupConvertor implements BeanJsonConvertor { + + private static Logger logger = LoggerFactory.getLogger(SecurityGroupConvertor.class); + + @Override + public List convertList(JSONArray array) { + List list = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + list.add(convertModel(array.getJSONObject(i))); + } + return list; + } + + @Override + public SecurityGroupModel convertModel(JSONObject object) { + SecurityGroupModel model = new SecurityGroupModel(); + model.setName(object.getString("sgName")); + model.setRemark(object.getString("sgRemark")); + model.setGroupUuid(object.getString("sgId")); + String createdTime = object.getString("createTime"); + if(!StringUtils.isEmpty(createdTime)){ + model.setCreateTime(DateTools.stringToDateTime(createdTime)); + } + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/SecurityGroupRuleConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/SecurityGroupRuleConvertor.java new file mode 100644 index 0000000..c084d35 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/SecurityGroupRuleConvertor.java @@ -0,0 +1,39 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.model.SecurityGroupRuleModel; +import com.bocloud.cmp.provider.convertor.BeanJsonConvertor; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: SecurityGroupRuleConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class SecurityGroupRuleConvertor implements BeanJsonConvertor { + + private static Logger logger = LoggerFactory.getLogger(SecurityGroupRuleConvertor.class); + + @Override + public List convertList(JSONArray array) { + List list = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + list.add(convertModel(array.getJSONObject(i))); + } + return list; + } + + @Override + public SecurityGroupRuleModel convertModel(JSONObject object) { + SecurityGroupRuleModel model = new SecurityGroupRuleModel(); + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/ServerConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/ServerConvertor.java new file mode 100644 index 0000000..7ffcb70 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/ServerConvertor.java @@ -0,0 +1,106 @@ +package com.bocloud.cmp.tceconvertor; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.alibaba.fastjson.JSON; +import com.bocloud.cmp.model.ServerModel; +import com.bocloud.cmp.model.VolumeModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.common.utils.DateTools; +import com.tencentcloudapi.cvm.v20170312.models.DataDisk; +import com.tencentcloudapi.cvm.v20170312.models.Instance; +import com.tencentcloudapi.cvm.v20170312.models.InternetAccessible; +import com.tencentcloudapi.cvm.v20170312.models.LoginSettings; +import com.tencentcloudapi.cvm.v20170312.models.VirtualPrivateCloud; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: ServerConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class ServerConvertor implements BeanConvertor { + + @Override + public List convertList(List objects) { + List serverModels = new ArrayList(); + for (Instance object : objects) { + serverModels.add(convertModel(object)); + } + return serverModels; + } + + @Override + public ServerModel convertModel(Instance instance) { + ServerModel model = new ServerModel(); + model.setCpu(instance.getCPU().intValue()); + model.setMemory(BigDecimal.valueOf(instance.getMemory())); + model.setFlavorUuid(instance.getInstanceType()); + model.setImageUuid(instance.getImageId()); + model.setInstanceId(instance.getInstanceId()); + String instanceName = instance.getInstanceName(); + if ("未命名".equals(instanceName)) { + instanceName = instance.getInstanceId(); + } + if (!StringUtils.isEmpty(instance.getCreatedTime())) { + model.setGmtVmCreate(DateTools.transfer("yyyy-MM-dd'T'HH:mm:ssZ", instance.getCreatedTime(), "Z")); + } + model.setName(instanceName); + model.setStatus(instance.getInstanceState()); + String[] securityGroupIds = instance.getSecurityGroupIds(); + if (null != securityGroupIds && securityGroupIds.length > 0) { + model.setSecurityGroups(Arrays.asList(securityGroupIds)); + } + model.setSystemDiskCategory(instance.getSystemDisk().getDiskType()); + model.setOsName(instance.getOsName()); + model.setZone(instance.getPlacement().getZone()); + String[] privateIpAddresses = instance.getPrivateIpAddresses(); + if (null != privateIpAddresses && privateIpAddresses.length > 0) { + model.setPrivateIps(JSON.toJSONString(privateIpAddresses)); + } + String[] publicIpAddresses = instance.getPublicIpAddresses(); + if (null != publicIpAddresses && publicIpAddresses.length > 0) { + model.setPublicIps(JSON.toJSONString(publicIpAddresses)); + } + model.setSystemDiskSize(instance.getSystemDisk().getDiskSize().intValue()); + model.setSystemDiskCategory(instance.getSystemDisk().getDiskType()); + + model.setInstanceChargeType(instance.getInstanceChargeType()); + InternetAccessible internetAccessible = instance.getInternetAccessible(); + model.setInternetMaxBandwidthOut(internetAccessible.getInternetMaxBandwidthOut().intValue()); + model.setInternetChargeType(internetAccessible.getInternetChargeType()); + model.setIsUsePublicIp(internetAccessible.getPublicIpAssigned()); + + VirtualPrivateCloud virtualPrivateCloud = instance.getVirtualPrivateCloud(); + model.setNetworkUuid(virtualPrivateCloud.getVpcId()); + model.setSubnetUuid(virtualPrivateCloud.getSubnetId()); + + List diskDevices = new ArrayList<>(); + VolumeModel volumeModel; + DataDisk[] dataDisks = instance.getDataDisks(); + if (null != dataDisks && dataDisks.length > 0) { + for (DataDisk disk : dataDisks) { + volumeModel = new VolumeModel(); + volumeModel.setVolumeUuid(disk.getDiskId()); + volumeModel.setType(disk.getDiskType()); + volumeModel.setSize(disk.getDiskSize().intValue()); + diskDevices.add(volumeModel); + } + } + model.setDiskDevices(diskDevices); + LoginSettings loginSettings = instance.getLoginSettings(); + if (null != loginSettings) { + if (null != loginSettings.getKeyIds() && loginSettings.getKeyIds().length > 0) { + model.setKeypairName(JSON.toJSONString(loginSettings.getKeyIds())); + } + } + return model; + } + +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/SnapshotConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/SnapshotConvertor.java new file mode 100644 index 0000000..c11bc1e --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/SnapshotConvertor.java @@ -0,0 +1,48 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import com.bocloud.cmp.model.SnapshotModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.tencentcloudapi.cbs.v20170312.models.Snapshot; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: SnapshotConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class SnapshotConvertor implements BeanConvertor { + + @Override + public List convertList(List objects) { + List snapshotModels = new ArrayList(); + for (Snapshot object : objects) { + snapshotModels.add(convertModel(object)); + } + return snapshotModels; + } + + @Override + public SnapshotModel convertModel(Snapshot snapshot) { + SnapshotModel model = new SnapshotModel(); + model.setSize(snapshot.getDiskSize().intValue()); + String snapshotName = snapshot.getSnapshotName(); + if (null != snapshotName && "未命名".equals(snapshotName)) { + snapshotName = snapshot.getSnapshotId(); + } + model.setName(snapshotName); + model.setSnapshotUuid(snapshot.getSnapshotId()); + String snapshotState = snapshot.getSnapshotState(); + if ("NORMAL".equalsIgnoreCase(snapshotState)) { + model.setStatus("AVAILABLE"); // snapshotState + } else { + model.setStatus(snapshotState); + } + model.setVolumeUuid(snapshot.getDiskId()); + return model; + } + +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/SubnetConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/SubnetConvertor.java new file mode 100644 index 0000000..7bc38b3 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/SubnetConvertor.java @@ -0,0 +1,52 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.model.SubnetModel; +import com.bocloud.cmp.provider.convertor.BeanJsonConvertor; +import com.bocloud.common.utils.DateTools; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: SubnetConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class SubnetConvertor implements BeanJsonConvertor { + + @Override + public List convertList(JSONArray array) { + List list = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + list.add(convertModel(array.getJSONObject(i))); + } + return list; + } + + @Override + public SubnetModel convertModel(JSONObject object) { + SubnetModel model = new SubnetModel(); + model.setName(object.getString("subnetName")); + model.setSubnetUuid(object.getString("unSubnetId")); + model.setCidr(object.getString("cidrBlock")); + model.setNetworkUuid(object.getString("unVpcId")); + model.setVpcUuid(object.getString("unVpcId")); + model.setVpcName(object.getString("vpcName")); + model.setIsDefault(object.getBoolean("isDefault")); + model.setZone(object.getString("zone")); + model.setHostRoutes(object.getString("unRouteTableId")); + model.setZoneNum(object.getString("zoneId")); + model.setIpVersion("V4"); + String createdTime = object.getString("subnetCreateTime"); + if (StringUtils.isEmpty(createdTime)) { + model.setGmtCreate(DateTools.stringToDateTime(createdTime)); + } + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/VolumeConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/VolumeConvertor.java new file mode 100644 index 0000000..04bcf46 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/VolumeConvertor.java @@ -0,0 +1,75 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; + +import com.bocloud.cmp.model.VolumeModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.bocloud.common.utils.DateTools; +import com.tencentcloudapi.cbs.v20170312.models.Disk; +import com.tencentcloudapi.cbs.v20170312.models.Placement; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: VolumeConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class VolumeConvertor implements BeanConvertor { + + @Override + public List convertList(List objects) { + List volumeModels = new ArrayList(); + for (Disk object : objects) { + volumeModels.add(convertModel(object)); + } + return volumeModels; + } + + @Override + public VolumeModel convertModel(Disk disk) { + VolumeModel model = new VolumeModel(); + model.setVolumeUuid(disk.getDiskId()); + String diskName = disk.getDiskName(); + if (null != diskName && "未命名".equals(diskName)) { + diskName = disk.getDiskId(); + } + model.setName(diskName); + model.setSize(disk.getDiskSize().intValue()); + model.setType(disk.getDiskType()); + String diskState = disk.getDiskState(); + if ("ATTACHED".equalsIgnoreCase(diskState)) { + model.setStatus("IN_USE"); + } else if ("UNATTACHED".equalsIgnoreCase(diskState)) { + model.setStatus("AVAILABLE"); + } else { + model.setStatus(diskState); + } + // •PREPAID:预付费,即包年包月 + // •POSTPAID_BY_HOUR:后付费,即按量计费。 + model.setDiskChargeType(disk.getDiskChargeType()); + if (!StringUtils.isEmpty(disk.getDeadlineTime())) { + model.setDiskExpireTime(DateTools.stringToDateTime(disk.getDeadlineTime())); + } + model.setInstanceId(disk.getInstanceId()); + model.setDeleteWithInstance(disk.getDeleteWithInstance()); + model.setBootVolume(disk.getDeleteWithInstance()); + Placement placement = disk.getPlacement(); + model.setZone(placement.getZone()); + // •SYSTEM_DISK:系统盘 + // •DATA_DISK:数据盘。 + String diskUsage = disk.getDiskUsage(); + model.setUsage(disk.getDiskUsage()); + if (null != diskUsage && "SYSTEM_DISK".equalsIgnoreCase(diskUsage)) { + model.setBootVolume(true); + } + if (!StringUtils.isEmpty(disk.getCreateTime())) { + model.setCreateTime(DateTools.stringToDateTime(disk.getCreateTime())); + } + return model; + } + +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/VpcConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/VpcConvertor.java new file mode 100644 index 0000000..8d8f68f --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/VpcConvertor.java @@ -0,0 +1,50 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.bocloud.cmp.model.VpcModel; +import com.bocloud.cmp.provider.convertor.BeanJsonConvertor; +import com.bocloud.common.utils.DateTools; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: VpcConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class VpcConvertor implements BeanJsonConvertor { + + private static Logger logger = LoggerFactory.getLogger(VpcConvertor.class); + + @Override + public List convertList(JSONArray array) { + List list = new ArrayList<>(); + for (int i = 0; i < array.size(); i++) { + list.add(convertModel(array.getJSONObject(i))); + } + return list; + } + + @Override + public VpcModel convertModel(JSONObject object) { + VpcModel model = new VpcModel(); + model.setVpcId(object.getString("unVpcId")); + model.setName(object.getString("vpcName")); + model.setCidr(object.getString("cidrBlock")); + model.setDefaultVpc(object.getBoolean("isDefault")); + model.setStatus("ACTIVE"); + String createdTime = object.getString("createTime"); + if(!StringUtils.isEmpty(createdTime)){ + model.setGmtCreate(DateTools.stringToDateTime(createdTime)); + } + return model; + } +} diff --git a/src/main/java/com/bocloud/cmp/tceconvertor/ZoneConvertor.java b/src/main/java/com/bocloud/cmp/tceconvertor/ZoneConvertor.java new file mode 100644 index 0000000..5ac63c0 --- /dev/null +++ b/src/main/java/com/bocloud/cmp/tceconvertor/ZoneConvertor.java @@ -0,0 +1,38 @@ +package com.bocloud.cmp.tceconvertor; + +import java.util.ArrayList; +import java.util.List; + +import com.bocloud.cmp.model.ZoneModel; +import com.bocloud.cmp.provider.convertor.BeanConvertor; +import com.tencentcloudapi.cvm.v20170312.models.ZoneInfo; + +/** + * @Company: 博云 www.bocloud.com + * @ClassName: ZoneConvertor + * @Description: + * @author: zhenpingLi/李振平 + * @date: 2019/10/28 16:47 + */ +public class ZoneConvertor implements BeanConvertor { + + @Override + public List convertList(List objects) { + List regionModels = new ArrayList(); + for (ZoneInfo object : objects) { + if ("AVAILABLE".equalsIgnoreCase(object.getZoneState())) { + regionModels.add(convertModel(object)); + } + } + return regionModels; + } + + @Override + public ZoneModel convertModel(ZoneInfo info) { + ZoneModel model = new ZoneModel(); + model.setName(info.getZoneName()); + model.setZoneId(info.getZone()); + model.setZoneNum(info.getZoneId()); + return model; + } +} diff --git a/src/main/resource/tce.sql b/src/main/resource/tce.sql new file mode 100644 index 0000000..1168e5e --- /dev/null +++ b/src/main/resource/tce.sql @@ -0,0 +1,5 @@ +ALTER TABLE `subnet` ADD COLUMN `zone_id` VARCHAR(16) DEFAULT NULL COMMENT '可用区id'; + +ALTER TABLE `security_group_rule` ADD COLUMN `sgr_index` INT(10) DEFAULT NULL COMMENT '安全组规则下标'; + +ALTER TABLE `zone` ADD COLUMN `zone_num` VARCHAR(32) DEFAULT NULL COMMENT 'aws和tce等数字化id';