├── .gitignore
├── src
└── main
│ ├── resources
│ ├── db.properties
│ ├── logback.xml
│ ├── config.properties
│ ├── script
│ │ ├── create.sql
│ │ └── init.sql
│ └── logger-prod.xml
│ └── java
│ └── com
│ └── qianmi
│ ├── DeployException.java
│ ├── Constants.java
│ ├── service
│ ├── BaseService.java
│ ├── AliyunRegionService.java
│ ├── AliyunEipService.java
│ ├── AliyunImageService.java
│ ├── ApiUtil.java
│ └── AliyunInstanceService.java
│ ├── models
│ ├── BaseHelper.java
│ ├── Region.java
│ ├── UserInstanceHelper.java
│ ├── RegionHelper.java
│ ├── SystemType.java
│ ├── SystemTypeHelper.java
│ ├── UserInstance.java
│ ├── SystemOSHelper.java
│ ├── SystemOS.java
│ └── DBUtil.java
│ ├── Bootstrap.java
│ ├── form
│ ├── InstanceResult.java
│ ├── InstanceStatus.java
│ └── InstanceForm.java
│ ├── proxy
│ └── InstanceProxy.java
│ └── controller
│ └── WebController.java
├── README.md
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | target
3 | *.iml
4 |
--------------------------------------------------------------------------------
/src/main/resources/db.properties:
--------------------------------------------------------------------------------
1 | jdbc.url=jdbc:h2:./cloudeploy;INIT=runscript from 'classpath:/script/create.sql'\\;runscript from 'classpath:/script/init.sql'
2 | jdbc.user=sa
3 | jdbc.password=
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/DeployException.java:
--------------------------------------------------------------------------------
1 | package com.qianmi;
2 |
3 | /**
4 | * 自定义接口异常
5 | */
6 | public class DeployException extends Exception {
7 | private String code;
8 | public DeployException(String code, String message) {
9 | super(message);
10 | this.code = code;
11 | }
12 | public String getCode() {
13 | return code;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/Constants.java:
--------------------------------------------------------------------------------
1 | package com.qianmi;
2 |
3 | /**
4 | * Created by li on 15/5/16.
5 | */
6 | public class Constants {
7 | private Constants() {
8 |
9 | }
10 |
11 | /**
12 | * 阿里云平台
13 | */
14 | public static final String PLATFORM_ALIYUN = "aliyun";
15 | /**
16 | * UCLOUD平台
17 | */
18 | public static final String PLATFORM_UCLOUD = "ucloud";
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/service/BaseService.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.service;
2 |
3 | import com.aliyun.api.AliyunClient;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | public class BaseService {
8 | protected final transient Logger logger = LoggerFactory.getLogger(getClass());
9 |
10 | protected AliyunClient client;
11 |
12 | public BaseService() {
13 | this.client = ApiUtil.getInstance().getAliyunClient();
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/BaseHelper.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.dbutils.QueryRunner;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | public class BaseHelper {
8 | protected final transient Logger logger = LoggerFactory.getLogger(getClass());
9 |
10 | protected QueryRunner runner = null;
11 | protected String tableName;
12 |
13 | public BaseHelper(String tableName) {
14 | this.tableName = tableName;
15 | this.runner = DBUtil.getInstance().getRunner();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/resources/config.properties:
--------------------------------------------------------------------------------
1 | aliyun.serverUrl=http://ecs.aliyuncs.com/
2 | aliyun.accessKeyId=xxxxx
3 | aliyun.accessKeySecret=xxxxx
4 | platform.default=aliyun
5 |
6 | # instance default value
7 | aliyun.instance.RegionId=cn-hangzhou
8 | aliyun.instance.ImageId=centos6u5_64_20G_aliaegis_20150130.vhd
9 | aliyun.instance.InstanceType=ecs.t1.small
10 | aliyun.instance.SecurityGroupId=sg-237gsmw7r
11 | aliyun.instance.InternetChargeType=PayByTraffic
12 | aliyun.instance.InternetMaxBandwidthOut=1
13 | aliyun.instance.password=pwd123
14 |
15 | ucloud.instance.RegionId=
16 |
--------------------------------------------------------------------------------
/src/main/resources/script/create.sql:
--------------------------------------------------------------------------------
1 | -- os
2 | CREATE TABLE system_os(
3 | name VARCHAR(50),
4 | `bit` VARCHAR(10),
5 | version VARCHAR(50),
6 | platform VARCHAR(50),
7 | image VARCHAR(255)
8 | );
9 |
10 | CREATE TABLE system_type(
11 | cpu INT(10),
12 | memory INT(10),
13 | platform VARCHAR(50),
14 | code VARCHAR(255)
15 | );
16 |
17 | CREATE TABLE user_instance (
18 | user VARCHAR(100),
19 | instanceId VARCHAR(255),
20 | instanceIp VARCHAR(255),
21 | platform VARCHAR(50)
22 | );
23 |
24 | CREATE TABLE region (
25 | id VARCHAR(100),
26 | name VARCHAR(100),
27 | platform VARCHAR(50)
28 | );
29 |
30 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/Bootstrap.java:
--------------------------------------------------------------------------------
1 | package com.qianmi;
2 |
3 | import com.qianmi.controller.WebController;
4 | import com.qianmi.models.DBUtil;
5 | import com.qianmi.service.ApiUtil;
6 | import org.h2.tools.Server;
7 |
8 | import java.io.IOException;
9 | import java.sql.SQLException;
10 |
11 | /**
12 | * 应用入口
13 | */
14 | public class Bootstrap {
15 |
16 | public static void main(String[] args) throws NullPointerException, IOException, SQLException {
17 |
18 | // db console
19 | Server.createWebServer().start();
20 |
21 | // web
22 | new WebController();
23 |
24 | ApiUtil.getInstance();
25 | DBUtil.getInstance();
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/form/InstanceResult.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.form;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 |
5 | /**
6 | * 实例创建结果
7 | */
8 | public class InstanceResult {
9 |
10 | /**
11 | * 实例ID
12 | */
13 | private String instanceId;
14 |
15 | /**
16 | * 实例IP
17 | */
18 | private String ip;
19 |
20 | public InstanceResult(String instanceId, String ip) {
21 | this.instanceId = instanceId;
22 | this.ip = ip;
23 | }
24 |
25 | public String getInstanceId() {
26 | return instanceId;
27 | }
28 |
29 | public void setInstanceId(String instanceId) {
30 | this.instanceId = instanceId;
31 | }
32 |
33 | public String getIp() {
34 | return ip;
35 | }
36 |
37 | public void setIp(String ip) {
38 | this.ip = ip;
39 | }
40 |
41 | @Override
42 | public String toString() {
43 | return new ToStringBuilder(this)
44 | .append("instanceId", instanceId)
45 | .append("ip", ip)
46 | .toString();
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/Region.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 |
5 | /**
6 | * 区域
7 | */
8 | public class Region {
9 | /**
10 | * 区域id
11 | */
12 | private String id;
13 | /**
14 | * 区域名称
15 | */
16 | private String name;
17 | /**
18 | * 平台名称
19 | */
20 | private String platform;
21 |
22 | public String getId() {
23 | return id;
24 | }
25 |
26 | public void setId(String id) {
27 | this.id = id;
28 | }
29 |
30 | public String getName() {
31 | return name;
32 | }
33 |
34 | public void setName(String name) {
35 | this.name = name;
36 | }
37 |
38 | public String getPlatform() {
39 | return platform;
40 | }
41 |
42 | public void setPlatform(String platform) {
43 | this.platform = platform;
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | return new ToStringBuilder(this)
49 | .append("id", id)
50 | .append("name", name)
51 | .append("platform", platform)
52 | .toString();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/UserInstanceHelper.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.dbutils.ResultSetHandler;
4 | import org.apache.commons.dbutils.handlers.BeanHandler;
5 |
6 | import java.sql.SQLException;
7 |
8 | /**
9 | * Created by li on 15/5/14.
10 | */
11 | public class UserInstanceHelper extends BaseHelper {
12 |
13 | public UserInstanceHelper() {
14 | super("user_instance");
15 | }
16 |
17 | public UserInstance findByUser(String user) {
18 | logger.debug("find {} By user:{}", tableName, user);
19 | ResultSetHandler h = new BeanHandler(UserInstance.class);
20 | UserInstance ui = null;
21 | try {
22 | ui = runner.query("SELECT * FROM " + tableName + " WHERE user=?", h, user);
23 | } catch (SQLException e) {
24 | logger.error("findByUser {} error:", tableName, e);
25 | }
26 | return ui;
27 | }
28 |
29 | public int add(UserInstance u) {
30 | logger.debug("add user:{}", u);
31 | try {
32 | return runner.update("INSERT INTO " + tableName + "(user, instanceId, instanceIp, platform) VALUES(?,?,?,?)",
33 | u.getUser(), u.getInstanceId(), u.getInstanceIp(), u.getPlatform());
34 | } catch (SQLException e) {
35 | logger.error("insert {} error:", tableName, e);
36 | }
37 | return 0;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/service/AliyunRegionService.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.service;
2 |
3 | import com.aliyun.api.domain.Region;
4 | import com.aliyun.api.ecs.ecs20130110.request.DescribeRegionsRequest;
5 | import com.aliyun.api.ecs.ecs20130110.response.DescribeRegionsResponse;
6 | import com.qianmi.DeployException;
7 | import com.taobao.api.ApiException;
8 | import org.apache.commons.lang3.StringUtils;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by li on 15/5/15.
14 | */
15 | public class AliyunRegionService extends BaseService {
16 |
17 | public List describeRegions() throws DeployException {
18 | DescribeRegionsRequest request = new DescribeRegionsRequest();
19 | try {
20 | DescribeRegionsResponse response = client.execute(request);
21 | if (StringUtils.isNotEmpty(response.getErrorCode())) {
22 | logger.error("code:{}, msg:{}", response.getErrorCode(), response.getMessage());
23 | throw new DeployException(response.getErrorCode(), response.getMessage());
24 | }
25 | // return list.stream().configCache(Region::getLocalName).collect(Collectors.toList());
26 | return response.getRegions();
27 | } catch (ApiException e) {
28 | logger.error("code:{}, msg:{}", e.getErrCode(), e.getMessage(), e);
29 | throw new DeployException(e.getErrCode(), e.getErrMsg());
30 | }
31 |
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/RegionHelper.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.dbutils.ResultSetHandler;
4 | import org.apache.commons.dbutils.handlers.BeanHandler;
5 | import org.apache.commons.dbutils.handlers.BeanListHandler;
6 |
7 | import java.sql.SQLException;
8 | import java.util.List;
9 |
10 | /**
11 | * Created by li on 15/5/15.
12 | */
13 | public class RegionHelper extends BaseHelper {
14 | public RegionHelper() {
15 | super("region");
16 | }
17 |
18 | public List all() {
19 | ResultSetHandler> h = new BeanListHandler(Region.class);
20 | List regions = null;
21 | try {
22 | regions = runner.query("SELECT * FROM " + tableName, h);
23 | } catch (SQLException e) {
24 | logger.error("select all {} error:", tableName, e);
25 | }
26 | return regions;
27 | }
28 |
29 | public Region findOne(String id, String platform) {
30 | logger.debug("find {} By id:{}, platform:{}", tableName, id, platform);
31 | ResultSetHandler h = new BeanHandler(Region.class);
32 | Region region = null;
33 | try {
34 | region = runner.query("SELECT * FROM " + tableName + " WHERE id=? AND platform=?",
35 | h, id, platform);
36 | } catch (SQLException e) {
37 | logger.error("find {} error:", tableName, e);
38 | }
39 | return region;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/SystemType.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 |
5 | /**
6 | * 平台机器配置类型
7 | */
8 | public class SystemType implements java.io.Serializable {
9 | /**
10 | * cpu个数
11 | */
12 | private int cpu;
13 | /**
14 | * 内存大小
15 | */
16 | private int memory;
17 |
18 | /**
19 | * 平台(aliyun,ucloud)
20 | */
21 | private String platform;
22 |
23 | /**
24 | * 规格类型代码
25 | */
26 | private String code;
27 |
28 | public int getCpu() {
29 | return cpu;
30 | }
31 |
32 | public void setCpu(int cpu) {
33 | this.cpu = cpu;
34 | }
35 |
36 | public int getMemory() {
37 | return memory;
38 | }
39 |
40 | public void setMemory(int memory) {
41 | this.memory = memory;
42 | }
43 |
44 | public String getPlatform() {
45 | return platform;
46 | }
47 |
48 | public void setPlatform(String platform) {
49 | this.platform = platform;
50 | }
51 |
52 | public String getCode() {
53 | return code;
54 | }
55 |
56 | public void setCode(String code) {
57 | this.code = code;
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return new ToStringBuilder(this)
63 | .append("cpu", cpu)
64 | .append("memory", memory)
65 | .append("platform", platform)
66 | .append("code", code)
67 | .toString();
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/service/AliyunEipService.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.service;
2 |
3 | import com.aliyun.api.ecs.ecs20130110.request.AllocatePublicIpAddressRequest;
4 | import com.aliyun.api.ecs.ecs20130110.response.AllocatePublicIpAddressResponse;
5 | import com.qianmi.DeployException;
6 | import com.taobao.api.ApiException;
7 | import org.apache.commons.lang3.StringUtils;
8 |
9 | /**
10 | * 公网ip
11 | */
12 | public class AliyunEipService extends BaseService {
13 |
14 | /**
15 | * 给实例分配IP
16 | * @param instanceId 实例ID
17 | * @return 分配的IP
18 | * @throws DeployException
19 | */
20 | public String allocatePublicIpAddress(String instanceId) throws DeployException {
21 | logger.debug("allocate ip to instanceId:{}", instanceId);
22 | AllocatePublicIpAddressRequest request = new AllocatePublicIpAddressRequest();
23 | request.setInstanceId(instanceId);
24 | try {
25 | AllocatePublicIpAddressResponse response = client.execute(request);
26 | if (StringUtils.isNotEmpty(response.getErrorCode())) {
27 | logger.error("code:{}, msg:{}", response.getErrorCode(), response.getMessage());
28 | throw new DeployException(response.getErrorCode(), response.getMessage());
29 | }
30 | return response.getIpAddress();
31 | } catch (ApiException e) {
32 | logger.error("code:{}, msg:{}", e.getErrCode(), e.getMessage(), e);
33 | throw new DeployException(e.getErrCode(), e.getErrMsg());
34 | }
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/SystemTypeHelper.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.dbutils.ResultSetHandler;
4 | import org.apache.commons.dbutils.handlers.BeanHandler;
5 | import org.apache.commons.dbutils.handlers.BeanListHandler;
6 |
7 | import java.sql.SQLException;
8 | import java.util.List;
9 |
10 | /**
11 | * Created by li on 15/5/14.
12 | */
13 | public class SystemTypeHelper extends BaseHelper {
14 |
15 | public SystemTypeHelper() {
16 | super("system_type");
17 | }
18 |
19 | public List all() {
20 | ResultSetHandler> hos = new BeanListHandler(SystemType.class);
21 | List types = null;
22 | try {
23 | types = runner.query("SELECT * FROM " + tableName, hos);
24 | } catch (SQLException e) {
25 | logger.error("select all {} error:", tableName, e);
26 | }
27 | return types;
28 | }
29 |
30 | public SystemType findOne(int cpu, int memory, String platform) {
31 | logger.debug("find {} By cpu:{}, memory:{}, platform:{}", tableName, cpu, memory, platform);
32 | ResultSetHandler h = new BeanHandler(SystemType.class);
33 | SystemType type = null;
34 | try {
35 | type = runner.query(
36 | "SELECT * FROM " + tableName + " WHERE cpu=? AND memory=? AND platform=?",
37 | h, cpu, memory, platform);
38 | } catch (SQLException e) {
39 | logger.error("find {} error:", tableName, e);
40 | }
41 | return type;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/UserInstance.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 |
5 | /**
6 | * 用户实例关系
7 | */
8 | public class UserInstance {
9 | /**
10 | * 用户标示
11 | */
12 | private String user;
13 | /**
14 | * 实例ID
15 | */
16 | private String instanceId;
17 | /**
18 | * 实例IP
19 | */
20 | private String instanceIp;
21 | /**
22 | * 平台名称
23 | */
24 | private String platform;
25 |
26 | public String getUser() {
27 | return user;
28 | }
29 |
30 | public void setUser(String user) {
31 | this.user = user;
32 | }
33 |
34 | public String getInstanceId() {
35 | return instanceId;
36 | }
37 |
38 | public void setInstanceId(String instanceId) {
39 | this.instanceId = instanceId;
40 | }
41 |
42 | public String getInstanceIp() {
43 | return instanceIp;
44 | }
45 |
46 | public void setInstanceIp(String instanceIp) {
47 | this.instanceIp = instanceIp;
48 | }
49 |
50 | public String getPlatform() {
51 | return platform;
52 | }
53 |
54 | public void setPlatform(String platform) {
55 | this.platform = platform;
56 | }
57 |
58 | @Override
59 | public String toString() {
60 | return new ToStringBuilder(this)
61 | .append("user", user)
62 | .append("instanceId", instanceId)
63 | .append("instanceIp", instanceIp)
64 | .append("platform", platform)
65 | .toString();
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/service/AliyunImageService.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.service;
2 |
3 | import com.aliyun.api.domain.Image;
4 | import com.aliyun.api.ecs.ecs20130110.request.DescribeImagesRequest;
5 | import com.aliyun.api.ecs.ecs20130110.response.DescribeImagesResponse;
6 | import com.qianmi.DeployException;
7 | import com.taobao.api.ApiException;
8 | import org.apache.commons.lang3.StringUtils;
9 |
10 | import java.util.List;
11 |
12 | /**
13 | * Created by li on 15/5/14.
14 | */
15 | public class AliyunImageService extends BaseService {
16 |
17 | /**
18 | * 查询可用镜像列表
19 | * @param regionId 区域ID
20 | * @throws DeployException
21 | */
22 | public List describeImages(String regionId) throws DeployException {
23 | logger.debug("list images By regionId:{}", regionId);
24 | DescribeImagesRequest request = new DescribeImagesRequest();
25 | request.setRegionId(regionId);
26 | request.setPageSize(50L);
27 | try {
28 | DescribeImagesResponse response = client.execute(request);
29 | if (StringUtils.isNotEmpty(response.getErrorCode())) {
30 | logger.error("code:{}, msg:{}", response.getErrorCode(), response.getMessage());
31 | throw new DeployException(response.getErrorCode(), response.getMessage());
32 | }
33 | return response.getImages();
34 | } catch (ApiException e) {
35 | logger.error("code:{}, msg:{}", e.getErrCode(), e.getMessage(), e);
36 | throw new DeployException(e.getErrCode(), e.getErrMsg());
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/SystemOSHelper.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.dbutils.ResultSetHandler;
4 | import org.apache.commons.dbutils.handlers.BeanHandler;
5 | import org.apache.commons.dbutils.handlers.BeanListHandler;
6 |
7 | import java.sql.SQLException;
8 | import java.util.List;
9 |
10 | /**
11 | * Created by li on 15/5/14.
12 | */
13 | public class SystemOSHelper extends BaseHelper {
14 |
15 | public SystemOSHelper() {
16 | super("system_os");
17 | }
18 |
19 | public List all() {
20 | ResultSetHandler> h = new BeanListHandler(SystemOS.class);
21 | List oses = null;
22 | try {
23 | oses = runner.query("SELECT * FROM " + tableName, h);
24 | } catch (SQLException e) {
25 | logger.error("select all {} error:", tableName, e);
26 | }
27 | return oses;
28 | }
29 |
30 | public SystemOS findOne(String name, String bit, String version, String platform) {
31 | logger.debug("find {} By name:{}, bit:{}, version:{}, platform:{}", tableName, name, bit, version, platform);
32 | ResultSetHandler h = new BeanHandler(SystemOS.class);
33 | SystemOS os = null;
34 | try {
35 | os = runner.query(
36 | "SELECT * FROM " + tableName + " WHERE name=? AND bit=? AND version=? AND platform=?",
37 | h, name, bit, version, platform);
38 | } catch (SQLException e) {
39 | logger.error("find {} error:", tableName, e);
40 | }
41 | return os;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/SystemOS.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 |
5 | /**
6 | * 平台操作系统配置
7 | */
8 | public class SystemOS implements java.io.Serializable {
9 | /**
10 | * 操作系统
11 | * CentOS
12 | */
13 | private String name;
14 | /**
15 | * 操作系统位数(64,32)
16 | * 64
17 | */
18 | private String bit;
19 | /**
20 | * 操作系统版本(14.04)
21 | */
22 | private String version;
23 |
24 | /**
25 | * 平台(aliyun,ucloud)
26 | */
27 | private String platform;
28 |
29 | /**
30 | * 平台的image名称
31 | */
32 | private String image;
33 |
34 | public String getName() {
35 | return name;
36 | }
37 |
38 | public void setName(String name) {
39 | this.name = name;
40 | }
41 |
42 | public String getBit() {
43 | return bit;
44 | }
45 |
46 | public void setBit(String bit) {
47 | this.bit = bit;
48 | }
49 |
50 | public String getVersion() {
51 | return version;
52 | }
53 |
54 | public void setVersion(String version) {
55 | this.version = version;
56 | }
57 |
58 | public String getPlatform() {
59 | return platform;
60 | }
61 |
62 | public void setPlatform(String platform) {
63 | this.platform = platform;
64 | }
65 |
66 | public String getImage() {
67 | return image;
68 | }
69 |
70 | public void setImage(String image) {
71 | this.image = image;
72 | }
73 |
74 | @Override
75 | public String toString() {
76 | return new ToStringBuilder(this)
77 | .append("name", name)
78 | .append("bit", bit)
79 | .append("version", version)
80 | .append("platform", platform)
81 | .append("image", image)
82 | .toString();
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/form/InstanceStatus.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.form;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 |
5 | /**
6 | * 实例查询结果
7 | */
8 | public class InstanceStatus {
9 | /**
10 | * 实例ID
11 | */
12 | private String instanceId;
13 | /**
14 | * 实例状态
15 | * Running
16 | * Stopped
17 | *
18 | */
19 | private String status;
20 |
21 | /**
22 | * 公网ip
23 | */
24 | private String publicIp;
25 |
26 | /**
27 | * 内网ip
28 | */
29 | private String innerIp;
30 |
31 | public InstanceStatus(String instanceId, String status, String publicIp, String innerIp) {
32 | this.instanceId = instanceId;
33 | this.status = status;
34 | this.publicIp = publicIp;
35 | this.innerIp = innerIp;
36 | }
37 |
38 | public String getInstanceId() {
39 | return instanceId;
40 | }
41 |
42 | public void setInstanceId(String instanceId) {
43 | this.instanceId = instanceId;
44 | }
45 |
46 | public String getStatus() {
47 | return status;
48 | }
49 |
50 | public void setStatus(String status) {
51 | this.status = status;
52 | }
53 |
54 | public String getPublicIp() {
55 | return publicIp;
56 | }
57 |
58 | public void setPublicIp(String publicIp) {
59 | this.publicIp = publicIp;
60 | }
61 |
62 | public String getInnerIp() {
63 | return innerIp;
64 | }
65 |
66 | public void setInnerIp(String innerIp) {
67 | this.innerIp = innerIp;
68 | }
69 |
70 | @Override
71 | public String toString() {
72 | return new ToStringBuilder(this)
73 | .append("instanceId", instanceId)
74 | .append("status", status)
75 | .append("publicIp", publicIp)
76 | .append("innerIp", innerIp)
77 | .toString();
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/resources/logger-prod.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | WARN
8 |
9 | ${path}/logs/error.log
10 |
11 | ${path}/logs/error-%d{yyyy-MM-dd}.gz
12 | 10
13 |
14 |
15 | %d{yyyy-MM-dd HH:mm:ss} - %-5level - from %logger in %thread %n%message%n%xException%n
16 |
17 |
18 |
19 |
20 | ${path}/logs/access.log
21 |
22 | ${path}/logs/access-%i.log
23 | 1
24 | 10
25 |
26 |
27 | 50MB
28 |
29 |
30 | %d{MM-dd HH:mm:ss.SSS} - %-5level - from %logger in %thread %msg%n
31 | true
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/main/resources/script/init.sql:
--------------------------------------------------------------------------------
1 |
2 | -- aliyun
3 | INSERT INTO system_os(name, bit, version, platform, image) VALUES ('centos','64','7.0','aliyun','centos7u0_64_20G_aliaegis_20150130.vhd');
4 | INSERT INTO system_os(name, bit, version, platform, image) VALUES ('centos','64','6.5','aliyun','centos6u5_64_20G_aliaegis_20150130.vhd');
5 | INSERT INTO system_os(name, bit, version, platform, image) VALUES ('centos','32','6.5','aliyun','centos6u5_32_20G_aliaegis_20150130.vhd');
6 | INSERT INTO system_os(name, bit, version, platform, image) VALUES ('centos','64','5.8','aliyun','centos5u8_64_20G_aliaegis_20150130.vhd');
7 | INSERT INTO system_os(name, bit, version, platform, image) VALUES ('centos','64','5.10','aliyun','centos5u10_64_20G_aliaegis_20150130.vhd');
8 | INSERT INTO system_os(name, bit, version, platform, image) VALUES ('centos','32','5.10','aliyun','centos5u10_32_20G_aliaegis_20150130.vhd');
9 |
10 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (1,1,'aliyun','ecs.t1.small');
11 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (1,2,'aliyun','ecs.s1.small');
12 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (1,4,'aliyun','ecs.s1.medium');
13 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (1,8,'aliyun','ecs.s1.large');
14 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (2,2,'aliyun','ecs.s2.small');
15 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (2,4,'aliyun','ecs.s2.large');
16 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (2,8,'aliyun','ecs.s2.xlarge');
17 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (2,16,'aliyun','ecs.s2.2xlarge');
18 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (4,4,'aliyun','ecs.s3.medium');
19 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (4,8,'aliyun','ecs.s3.large');
20 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (4,16,'aliyun','ecs.m1.medium');
21 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (4,32,'aliyun','ecs.m2.medium');
22 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (8,32,'aliyun','ecs.m1.xlarge');
23 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (8,8,'aliyun','ecs.c1.small');
24 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (8,16,'aliyun','ecs.c1.large');
25 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (16,16,'aliyun','ecs.c2.medium');
26 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (16,32,'aliyun','ecs.c2.large');
27 | INSERT INTO system_type(cpu, memory, platform, code) VALUES (16,64,'aliyun','ecs.c2.xlarge');
28 |
29 | INSERT INTO region(id, name, platform) VALUES ('cn-shenzhen','深圳', 'aliyun');
30 | INSERT INTO region(id, name, platform) VALUES ('cn-qingdao','青岛', 'aliyun');
31 | INSERT INTO region(id, name, platform) VALUES ('cn-beijing','北京', 'aliyun');
32 | INSERT INTO region(id, name, platform) VALUES ('cn-hongkong','香港', 'aliyun');
33 | INSERT INTO region(id, name, platform) VALUES ('cn-hangzhou','杭州', 'aliyun');
34 | INSERT INTO region(id, name, platform) VALUES ('us-west-1','美国硅谷', 'aliyun');
35 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/models/DBUtil.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.models;
2 |
3 | import org.apache.commons.dbutils.QueryRunner;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.h2.jdbcx.JdbcConnectionPool;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.io.File;
10 | import java.io.FileInputStream;
11 | import java.io.IOException;
12 | import java.sql.SQLException;
13 | import java.util.Properties;
14 |
15 | /**
16 | * 数据库操作实例
17 | */
18 | public class DBUtil {
19 |
20 | private final transient Logger logger = LoggerFactory.getLogger(getClass());
21 |
22 | private static DBUtil instance = null;
23 |
24 | private JdbcConnectionPool connectionPool = null;
25 |
26 | private DBUtil() throws IOException {
27 | final Properties properties = new Properties();
28 | String dbFile = System.getProperty("db.file");
29 | if (dbFile != null) {
30 | properties.load(new FileInputStream(new File(dbFile)));
31 | } else {
32 | properties.load(Thread.currentThread().getClass().getResourceAsStream("/db.properties"));
33 | }
34 |
35 | String url = properties.getProperty("jdbc.url");
36 | String initSql = System.getProperty("init.sql");
37 |
38 | logger.debug("jdbc.url:{}", url);
39 | logger.debug("init.sql:{}", initSql);
40 |
41 | if (initSql == null || !initSql.toLowerCase().equals("true")) {
42 | url = url.substring(0, url.toLowerCase().indexOf("init"));
43 | }
44 | logger.debug("convert.jdbc.url:{}", url);
45 |
46 | this.connectionPool = JdbcConnectionPool.create(
47 | url,
48 | properties.getProperty("jdbc.user"),
49 | properties.getProperty("jdbc.password"));
50 | }
51 |
52 | public static synchronized DBUtil getInstance() {
53 | if (instance == null) {
54 | try {
55 | instance = new DBUtil();
56 | } catch (IOException e) {
57 | e.printStackTrace();
58 | }
59 | }
60 | return instance;
61 | }
62 |
63 | /**
64 | * H2内存数据库
65 | * @return 数据库链接,操作对象
66 | * @throws SQLException
67 | */
68 | public QueryRunner getRunner() {
69 | return new QueryRunner(connectionPool);
70 | }
71 |
72 | public static void main(String[] args) throws SQLException {
73 | SystemOSHelper systemOSHelper = new SystemOSHelper();
74 | // systemOSHelper.all().forEach(o -> System.out.println(o));
75 |
76 | SystemOS os = systemOSHelper.findOne(null, null, "7.0", "aliyun");
77 | System.out.println(os);
78 | //
79 | // SystemTypeHelper systemTypeHelper = new SystemTypeHelper();
80 | // SystemType type = systemTypeHelper.findOne(1, 1, "aliyun");
81 | // System.out.println(type);
82 | //
83 | // UserInstanceHelper uHelper = new UserInstanceHelper();
84 | // UserInstance ui = new UserInstance();
85 | // ui.setUser("zhangsan123");
86 | // ui.setInstanceId("fsdfsdf13323");
87 | // ui.setInstanceIp("123.902.22.222");
88 | // int result = uHelper.add(ui);
89 | // System.out.println("insert.result=" + result);
90 | //// systemTypeHelper.all().forEach(t -> System.out.println(t));
91 | //
92 | // RegionHelper regionHelper = new RegionHelper();
93 | // regionHelper.all().forEach(r -> System.out.println("r.id=" + r.getId()));
94 | // System.out.println(regionHelper.findOne("cn-qingdao", "a2liyun") == null);
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > Cloudeploy基于bugatti理念的极简云部署系统。
2 |
3 | 简介
4 | ---
5 | Cluodeploy是为解决客户私有云部署与监控,应用维护等问题统一处理平台。使用Cloudeploy可以快速创建主流云实例,安装等各种简化发布工作。
6 |
7 | 特性
8 | ---
9 | - 支持多平台创建实例
10 | - 阿里云
11 | - Ucloud
12 | - 极简接口,仅有3个RESTful API
13 | - 内嵌数据库
14 | - 可配置化
15 | - 小巧方便,仅8M大小的jar文件
16 |
17 | 安装
18 | ---
19 | 1. Oracle官方下载最新的[JDK8](http://www.oracle.com/technetwork/java/javase/downloads/index.html)
20 | 2. [版本发布页](https://github.com/QianmiOpen/cloudeploy/releases)下载最新的 **cloudeploy-1.0-RELEASE.jar**
21 | 3. 访问 **http://[hostname]:[port]/**在你的浏览器中,默认port:4567
22 |
23 | 默认是直接访问(没做任何限制),为了安全起见请配置iptable策略。
24 |
25 | 然后你用`java -jar cloudeploy-1.0-RELEASE.jar`即可启动应用。如果是首次启动请增加`-Dinit.sql=true`参数用于初始化数据库脚本,下面一些参数做更多自定义配置:
26 | - -Dconfig.file=[默认配置文件]
27 | - -Ddb.file=[数据库连接]
28 | - -Dlogback.configurationFile=[logback配置文件]
29 |
30 | Cloudeploy的升级只需替换cloudeploy.jar。所有的数据存储在./cloudeploy.mv.db,所以你想备份cloudepoy数据,拷贝一份该文件即可。
31 |
32 | 另外./cloudeploy.mv.db默认数据路径和初始化脚本是可以自定义的,在`-Ddb.file=[数据库连接]`中设置`jdbc.url=`参数值,
33 | ##### Database URLs
34 | *Embedded*
35 |
36 | `jdbc:h2:~/test` 'test' in the user home directory
37 | `jdbc:h2:/data/test` 'test' in the directory /data
38 | `jdbc:h2:./test` in the current(!) working directory
39 | 更多数据库知识请参考[H2 Database官方文档](http://www.h2database.com/)。
40 |
41 | 访问数据库:http://127.0.0.1:8082/
42 |
43 | 数据库文件./cloudeploy.mv.db应该妥善保管
44 |
45 | 接口
46 | ---
47 | **注意:**
48 | - 返回内容为json格式,通过响应状态码判断是否成功
49 | - 默认值参考相关表位于`/resources/script/init.sql`
50 | - 所有请求编码为UTF-8
51 |
52 | ### 创建新主机
53 | ```http
54 | POST http://localhost:4567/host/new
55 | ```
56 | 参数 | 意义 | 备注
57 | :--------------------------- | :--------------- | :----------------
58 | user | 客户标示 | 必填
59 | platform | 接口平台 | 默认为aliyun,还支持UCloud
60 | region | 实例创建所在区域 | 默认为cn-hangzhou,更多参考region表id字段
61 | osName | 操作系统名称 | 默认为CentOS,更多参考system_os表name字段
62 | osBit | 操作系统位数 | 默认为64,更多参考system_os表bit字段
63 | osVersion | 操作系统版本 | 默认为6.5,更多参考system_os表version字段
64 | cpu | cpu数量 | 默认为1,更多参考system_type表cpu字段
65 | memory | 内存大小 | 默认为1,更多参考system_type表memory字段
66 | password | 主机root密码 | 默认为pwd123
67 | internetChargeType | 网络类型 | 默认为流量计费PayByTraffic,还有固定带宽计费PayByBandwidth
68 | internetMaxBandwidthOut | 网络出口带宽 | 默认为1,即为1M
69 |
70 | *成功返回: status = 200*
71 | ```json
72 | {
73 | "instanceId":"xxx" # 实例ID,
74 | "ip":"xxx" # 实例IP
75 | }
76 | ```
77 | *参数错误:status = 400*
78 | ```json
79 | {
80 | "field1": "error_msg",
81 | "field2": "error_msg"
82 | ...
83 | }
84 | ```
85 | *系统异常:status = 500*
86 | ```json
87 | {
88 | "code": "xxx",
89 | "message": "xxx"
90 | }
91 | ```
92 | ### 查询主机状态
93 | ```http
94 | GET http://localhost:4567/host/status
95 | ```
96 | 参数 | 意义 | 备注
97 | :----------- | :------------ | :----------------
98 | instanceId | 实例(主机)ID | 必填,创建新主机时返回
99 |
100 | *成功返回: status = 200*,实例状态包括:运行中`Running` 启动中`Starting` 停止`Stopped`
101 | ```json
102 | {
103 | "instanceId":"xxx",
104 | "status":"xxx"
105 | }
106 |
107 | ```
108 | *参数错误:status = 400*
109 | ```json
110 | {
111 | "instanceId": "param is not empty"
112 | }
113 | ```
114 | *系统异常:status = 500*
115 | ```json
116 | {
117 | "code": "xxx",
118 | "message": "xxx"
119 | }
120 | ```
121 | ### 执行ansible命令
122 | ```http
123 | POST http://localhost:4567/ansible/send
124 | Content-Type:application/x-www-form-urlencoded
125 | ```
126 | 参数 | 意义 | 备注
127 | :----------- | :------------ | :----------------
128 | command | 命令行内容 | 必填,需要Base64.encode("command", "UTF-8")编码
129 |
130 | *成功返回: status = 200*
131 | ```json
132 | {
133 | "result":"xxx",
134 | }
135 | ```
136 | *参数错误:status = 400*
137 | ```json
138 | {
139 | "command": "param is not empty"
140 | }
141 | ```
142 | *系统异常:status = 500*
143 | ```json
144 | {
145 | "error": "xxx"
146 | }
147 | ```
148 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/form/InstanceForm.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.form;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 |
5 | /**
6 | * 实例接口参数
7 | */
8 | public class InstanceForm {
9 |
10 | /**
11 | * 用户
12 | */
13 | private String user;
14 | /**
15 | * 平台
16 | * aliyun,ucloud
17 | */
18 | private String platform;
19 | /**
20 | * 区域
21 | */
22 | private String region;
23 | /**
24 | * 操作系统名称
25 | * centos
26 | */
27 | private String osName;
28 | /**
29 | * 操作系统位数(64,32)
30 | * 64
31 | */
32 | private String osBit;
33 | /**
34 | * 操作系统版本(6.5)
35 | */
36 | private String osVersion;
37 | /**
38 | * cpu数量
39 | * 1,2,4,8,16
40 | */
41 | private String cpu;
42 | /**
43 | * 内存大小
44 | * 1,2,4,8,16,32,64
45 | */
46 | private String memory;
47 | /**
48 | * 机器密码
49 | * pwd123
50 | */
51 | private String password;
52 | /**
53 | * 计费方式
54 | * 按流量计费
55 | */
56 | private String internetChargeType;
57 | /**
58 | * 出口宽带大小
59 | * 1~200,默认1M,最大支持到20M.
60 | */
61 | private String internetMaxBandwidthOut;
62 |
63 | public String getUser() {
64 | return user;
65 | }
66 |
67 | public void setUser(String user) {
68 | this.user = user;
69 | }
70 |
71 | public String getPlatform() {
72 | return platform;
73 | }
74 |
75 | public void setPlatform(String platform) {
76 | this.platform = platform;
77 | }
78 |
79 | public String getRegion() {
80 | return region;
81 | }
82 |
83 | public void setRegion(String region) {
84 | this.region = region;
85 | }
86 |
87 | public String getOsName() {
88 | return osName;
89 | }
90 |
91 | public void setOsName(String osName) {
92 | this.osName = osName;
93 | }
94 |
95 | public String getOsBit() {
96 | return osBit;
97 | }
98 |
99 | public void setOsBit(String osBit) {
100 | this.osBit = osBit;
101 | }
102 |
103 | public String getOsVersion() {
104 | return osVersion;
105 | }
106 |
107 | public void setOsVersion(String osVersion) {
108 | this.osVersion = osVersion;
109 | }
110 |
111 | public String getCpu() {
112 | return cpu;
113 | }
114 |
115 | public void setCpu(String cpu) {
116 | this.cpu = cpu;
117 | }
118 |
119 | public String getMemory() {
120 | return memory;
121 | }
122 |
123 | public void setMemory(String memory) {
124 | this.memory = memory;
125 | }
126 |
127 | public String getPassword() {
128 | return password;
129 | }
130 |
131 | public void setPassword(String password) {
132 | this.password = password;
133 | }
134 |
135 | public String getInternetChargeType() {
136 | return internetChargeType;
137 | }
138 |
139 | public void setInternetChargeType(String internetChargeType) {
140 | this.internetChargeType = internetChargeType;
141 | }
142 |
143 | public String getInternetMaxBandwidthOut() {
144 | return internetMaxBandwidthOut;
145 | }
146 |
147 | public void setInternetMaxBandwidthOut(String internetMaxBandwidthOut) {
148 | this.internetMaxBandwidthOut = internetMaxBandwidthOut;
149 | }
150 |
151 | @Override
152 | public String toString() {
153 | return new ToStringBuilder(this)
154 | .append("user", user)
155 | .append("platform", platform)
156 | .append("region", region)
157 | .append("osName", osName)
158 | .append("osBit", osBit)
159 | .append("osVersion", osVersion)
160 | .append("cpu", cpu)
161 | .append("memory", memory)
162 | .append("password", password)
163 | .append("internetChargeType", internetChargeType)
164 | .append("internetMaxBandwidthOut", internetMaxBandwidthOut)
165 | .toString();
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/proxy/InstanceProxy.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.proxy;
2 |
3 | import com.aliyun.api.ecs.ecs20140526.request.CreateInstanceRequest;
4 | import com.qianmi.Constants;
5 | import com.qianmi.DeployException;
6 | import com.qianmi.form.InstanceForm;
7 | import com.qianmi.form.InstanceResult;
8 | import com.qianmi.models.SystemOS;
9 | import com.qianmi.models.SystemOSHelper;
10 | import com.qianmi.models.SystemType;
11 | import com.qianmi.models.SystemTypeHelper;
12 | import com.qianmi.service.AliyunEipService;
13 | import com.qianmi.service.AliyunInstanceService;
14 | import com.qianmi.service.ApiUtil;
15 | import org.apache.commons.lang3.StringUtils;
16 | import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
17 | import org.slf4j.Logger;
18 | import org.slf4j.LoggerFactory;
19 |
20 | /**
21 | * 实例代理
22 | */
23 | public class InstanceProxy {
24 |
25 | private final transient Logger logger = LoggerFactory.getLogger(InstanceProxy.class);
26 |
27 | /**
28 | * 新建实例(初始化机器,分配ip,启动)
29 | * @return 实例ID,IP
30 | */
31 | public InstanceResult newInstance(InstanceForm instanceForm) throws DeployException {
32 | instanceForm.setPlatform(StringUtils.defaultString(instanceForm.getPlatform(),
33 | ApiUtil.getInstance().getConfigCache().get("platform.default")));
34 |
35 | if (StringUtils.equalsIgnoreCase(Constants.PLATFORM_ALIYUN, instanceForm.getPlatform())) {
36 | CreateInstanceRequest request = new CreateInstanceRequest();
37 | logger.info("platform:{}", Constants.PLATFORM_ALIYUN);
38 |
39 | // image
40 | SystemOS os = new SystemOSHelper().findOne(instanceForm.getOsName(), instanceForm.getOsBit(),
41 | instanceForm.getOsVersion(), instanceForm.getPlatform());
42 | logger.debug("osName:{}, osBit:{}, osVersion:{}, platform:{}",
43 | instanceForm.getOsName(), instanceForm.getOsBit(), instanceForm.getOsVersion(), instanceForm.getPlatform());
44 | if (os != null) {
45 | logger.debug("systemOs:{}", os);
46 | request.setImageId(os.getImage());
47 | }
48 |
49 | // instanceType
50 | if (StringUtils.isNumeric(instanceForm.getCpu()) && StringUtils.isNumeric(instanceForm.getMemory())) {
51 | logger.debug("cpu.number:{}, memory.number:{}", instanceForm.getCpu(), instanceForm.getMemory());
52 | SystemType type = new SystemTypeHelper().findOne(
53 | Integer.parseInt(instanceForm.getCpu()), Integer.parseInt(instanceForm.getMemory()), instanceForm.getPlatform());
54 | if (type != null) {
55 | logger.debug("systemType:{}", type);
56 | request.setInstanceType(type.getCode());
57 | }
58 | }
59 |
60 | request.setRegionId(instanceForm.getRegion());
61 | request.setInternetChargeType(instanceForm.getInternetChargeType());
62 | request.setPassword(instanceForm.getPassword());
63 | if (StringUtils.isNumeric(instanceForm.getInternetMaxBandwidthOut())) {
64 | request.setInternetMaxBandwidthOut(Long.valueOf(instanceForm.getInternetMaxBandwidthOut()));
65 | }
66 |
67 | logger.debug("requestParam:{}", ReflectionToStringBuilder.toString(request));
68 |
69 | // 创建实例
70 | AliyunInstanceService instanceService = new AliyunInstanceService();
71 | String instanceId = instanceService.createInstance(request);
72 | logger.info("create instance({}) success", instanceId);
73 |
74 | // 分配公网IP
75 | AliyunEipService eipService = new AliyunEipService();
76 | String ip = eipService.allocatePublicIpAddress(instanceId);
77 | logger.info("allocate ip:{} to instance", ip);
78 |
79 | // 启动实例
80 | instanceService.startInstance(instanceId);
81 | logger.info("instance start...");
82 |
83 | return new InstanceResult(instanceId, ip);
84 | }
85 | // else if { }
86 | return new InstanceResult(Constants.PLATFORM_UCLOUD, "暂未启动该平台api");
87 | }
88 |
89 |
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/service/ApiUtil.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.service;
2 |
3 | import com.aliyun.api.AliyunClient;
4 | import com.aliyun.api.DefaultAliyunClient;
5 | import com.aliyun.api.ecs.ecs20140526.request.CreateInstanceRequest;
6 | import com.qianmi.DeployException;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.IOException;
11 | import java.util.Map;
12 | import java.util.Properties;
13 | import java.util.concurrent.ConcurrentHashMap;
14 |
15 | /**
16 | * cloud api连接配置
17 | */
18 | public class ApiUtil {
19 |
20 | private static ApiUtil instance = null;
21 | private static AliyunClient aliyunClient = null;
22 | private static final Map configCache = new ConcurrentHashMap<>();
23 |
24 | private ApiUtil() throws IOException {
25 | final Properties properties = new Properties();
26 | String configFile = System.getProperty("config.file");
27 | if (configFile != null) {
28 | properties.load(new FileInputStream(new File(configFile)));
29 | } else {
30 | properties.load(Thread.currentThread().getClass().getResourceAsStream("/config.properties"));
31 | }
32 | // init config cache
33 | properties.stringPropertyNames().forEach(key -> configCache.put(key, properties.getProperty(key)));
34 |
35 | // aliyun client
36 | String serverUrl = configCache.get("aliyun.serverUrl");
37 | String accessKeyId = configCache.get("aliyun.accessKeyId");
38 | String accessKeySecret = configCache.get("aliyun.accessKeySecret");
39 | aliyunClient = new DefaultAliyunClient(serverUrl, accessKeyId, accessKeySecret);
40 |
41 | // ucloud client
42 | }
43 |
44 | public static synchronized ApiUtil getInstance() {
45 | if (instance == null) {
46 | try {
47 | instance = new ApiUtil();
48 | } catch (IOException e) {
49 | e.printStackTrace();
50 | }
51 | }
52 | return instance;
53 | }
54 |
55 | public AliyunClient getAliyunClient() {
56 | return aliyunClient;
57 | }
58 |
59 | public Map getConfigCache() {
60 | return configCache;
61 | }
62 |
63 | public static void main(String[] args) {
64 |
65 | AliyunInstanceService aliyunInstanceService = new AliyunInstanceService();
66 | CreateInstanceRequest request = new CreateInstanceRequest();
67 | request.setImageId("centos6u5_64_20G_aliaegis_20150130.vhd");
68 | request.setInstanceType("ecs.t1.small");
69 | request.setRegionId("cn-hangzhou");
70 | request.setSecurityGroupId("sg-237gsmw7r");
71 | request.setInternetChargeType("PayByTraffic"); // 按量付费
72 | request.setInternetMaxBandwidthOut(1L);
73 |
74 | // try {
75 | // String instanceId = aliyunInstanceService.createInstance(request);
76 | //
77 | // // 分配公网IP
78 | // AliyunEipService eipService = new AliyunEipService();
79 | // String ip = eipService.allocatePublicIpAddress(instanceId);
80 | // } catch (DeployException e) {
81 | // e.printStackTrace();
82 | // }
83 |
84 | // 分配公网IP
85 | // AliyunEipService eipService = new AliyunEipService();
86 | // try {
87 | // String ip = eipService.allocatePublicIpAddress("");
88 | // } catch (DeployException e) {
89 | // e.printStackTrace();
90 | // }
91 |
92 | // 启动实例
93 | try {
94 | aliyunInstanceService.startInstance("i-23n9gwnle");
95 | } catch (DeployException e) {
96 | e.printStackTrace();
97 | }
98 |
99 | // try {
100 | // aliyunInstanceService.stopInstance("i-23k3edxjr");
101 | // } catch (DeployException e) {
102 | // // response error json
103 | // }
104 |
105 | // try {
106 | // InstanceStatus r = aliyunInstanceService.describeInstanceAttribute("i-23bnskcin");
107 | // System.out.println("r.id=" + r.getInstanceId() + ",status=" + r.getStatus());
108 | // } catch (DeployException e) {
109 | // e.printStackTrace();
110 | // }
111 |
112 | // AliyunRegionService regionService = new AliyunRegionService(client);
113 | // try {
114 | // regionService.describeRegions().forEach(r -> System.out.println("('"+r.getRegionId()+"','"+r.getLocalName()+"')"));
115 | // } catch (DeployException e) {
116 | // e.printStackTrace();
117 | // }
118 |
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/service/AliyunInstanceService.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.service;
2 |
3 | import com.aliyun.api.ecs.ecs20130110.request.DescribeInstanceAttributeRequest;
4 | import com.aliyun.api.ecs.ecs20130110.request.StartInstanceRequest;
5 | import com.aliyun.api.ecs.ecs20130110.request.StopInstanceRequest;
6 | import com.aliyun.api.ecs.ecs20130110.response.DescribeInstanceAttributeResponse;
7 | import com.aliyun.api.ecs.ecs20130110.response.StartInstanceResponse;
8 | import com.aliyun.api.ecs.ecs20130110.response.StopInstanceResponse;
9 | import com.aliyun.api.ecs.ecs20140526.request.CreateInstanceRequest;
10 | import com.aliyun.api.ecs.ecs20140526.response.CreateInstanceResponse;
11 | import com.qianmi.DeployException;
12 | import com.qianmi.form.InstanceStatus;
13 | import com.taobao.api.ApiException;
14 | import org.apache.commons.lang3.StringUtils;
15 |
16 | /**
17 | * 实例
18 | */
19 | public class AliyunInstanceService extends BaseService {
20 |
21 | /**
22 | * 创建实例
23 | * @return 实例ID
24 | */
25 | public String createInstance(CreateInstanceRequest request) throws DeployException {
26 | if (StringUtils.isEmpty(request.getImageId())) {
27 | request.setImageId(ApiUtil.getInstance().getConfigCache().get("aliyun.instance.ImageId"));
28 | }
29 | if (StringUtils.isEmpty(request.getInstanceType())) {
30 | request.setInstanceType(ApiUtil.getInstance().getConfigCache().get("aliyun.instance.InstanceType"));
31 | }
32 | if (StringUtils.isEmpty(request.getRegionId())) {
33 | request.setRegionId(ApiUtil.getInstance().getConfigCache().get("aliyun.instance.RegionId"));
34 | }
35 | if (StringUtils.isEmpty(request.getSecurityGroupId())) {
36 | request.setSecurityGroupId(ApiUtil.getInstance().getConfigCache().get("aliyun.instance.SecurityGroupId"));
37 | }
38 | if (StringUtils.isEmpty(request.getInternetChargeType())) {
39 | request.setInternetChargeType(ApiUtil.getInstance().getConfigCache().get("aliyun.instance.InternetChargeType")); // 按量付费
40 | }
41 | if (request.getInternetMaxBandwidthOut() == null) {
42 | request.setInternetMaxBandwidthOut(Long.parseLong(ApiUtil.getInstance().getConfigCache().get("aliyun.instance.InternetMaxBandwidthOut")));
43 | }
44 | if (StringUtils.isEmpty(request.getPassword())) {
45 | request.setPassword(ApiUtil.getInstance().getConfigCache().get("aliyun.instance.password"));
46 | }
47 | try {
48 | CreateInstanceResponse response = client.execute(request);
49 | if (StringUtils.isNotEmpty(response.getErrorCode())) {
50 | logger.error("code:{}, msg:{}", response.getErrorCode(), response.getMessage());
51 | throw new DeployException(response.getErrorCode(), response.getMessage());
52 | }
53 | return response.getInstanceId();
54 | } catch (ApiException e) {
55 | logger.error("code:{}, msg:{}", e.getErrCode(), e.getMessage(), e);
56 | throw new DeployException(e.getErrCode(), e.getErrMsg());
57 | }
58 | }
59 |
60 | /**
61 | * 启动实例
62 | * @param instanceId 实例ID
63 | * @throws DeployException
64 | */
65 | public void startInstance(String instanceId) throws DeployException {
66 | StartInstanceRequest request = new StartInstanceRequest();
67 | request.setInstanceId(instanceId);
68 | try {
69 | StartInstanceResponse response = client.execute(request);
70 | if (StringUtils.isNotEmpty(response.getErrorCode())) {
71 | logger.error("code:{}, msg:{}", response.getErrorCode(), response.getMessage());
72 | throw new DeployException(response.getErrorCode(), response.getMessage());
73 | }
74 | } catch (ApiException e) {
75 | logger.error("code:{}, msg:{}", e.getErrCode(), e.getMessage(), e);
76 | throw new DeployException(e.getErrCode(), e.getErrMsg());
77 | }
78 | }
79 |
80 | /**
81 | * 停止实例
82 | * @param instanceId 实例ID
83 | * @throws DeployException
84 | */
85 | public void stopInstance(String instanceId) throws DeployException {
86 | StopInstanceRequest request = new StopInstanceRequest();
87 | request.setInstanceId(instanceId);
88 | try {
89 | StopInstanceResponse response = client.execute(request);
90 | if (StringUtils.isNotEmpty(response.getErrorCode())) {
91 | logger.error("code:{}, msg:{}", response.getErrorCode(), response.getMessage());
92 | throw new DeployException(response.getErrorCode(), response.getMessage());
93 | }
94 | } catch (ApiException e) {
95 | logger.error("code:{}, msg:{}", e.getErrCode(), e.getMessage(), e);
96 | throw new DeployException(e.getErrCode(), e.getErrMsg());
97 | }
98 | }
99 |
100 | /**
101 | * 查询实例状态
102 | * @param instanceId 实例ID
103 | * @throws DeployException
104 | */
105 | public InstanceStatus describeInstanceAttribute(String instanceId) throws DeployException {
106 | logger.debug("find instanceId:{} status", instanceId);
107 | DescribeInstanceAttributeRequest request = new DescribeInstanceAttributeRequest();
108 | request.setInstanceId(instanceId);
109 | try {
110 | DescribeInstanceAttributeResponse response = client.execute(request);
111 | if (StringUtils.isNotEmpty(response.getErrorCode())) {
112 | logger.error("code:{}, msg:{}", response.getErrorCode(), response.getMessage());
113 | throw new DeployException(response.getErrorCode(), response.getMessage());
114 | }
115 |
116 | Object publicIp = response.getPublicIpAddress().size() > 0 ? response.getPublicIpAddress().get(0) : "";
117 | Object innerIp = response.getInnerIpAddress().size() > 0 ? response.getInnerIpAddress().get(0) : "";
118 | return new InstanceStatus(response.getInstanceId(), response.getStatus(), (String)publicIp, (String)innerIp);
119 | } catch (ApiException e) {
120 | logger.error("code:{}, msg:{}", e.getErrCode(), e.getMessage(), e);
121 | throw new DeployException(e.getErrCode(), e.getErrMsg());
122 | }
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 |
6 | com.ofpay
7 | of-parent
8 | 1.1.4-RELEASE
9 |
10 |
11 | com.qianmi
12 | cloudeploy
13 | 1.0-RELEASE
14 | jar
15 |
16 | cloudeploy
17 | http://maven.apache.org
18 |
19 |
20 | 1.8
21 | 1.8
22 | UTF-8
23 | http://git.dev.qianmi.com/tda/cloudeploy.git
24 |
25 |
26 |
27 | scm:git:${git.url}
28 | scm:git:${git.url}
29 | ${git.url}
30 | HEAD
31 |
32 |
33 |
34 |
35 | com.sparkjava
36 | spark-core
37 | 2.1
38 |
39 |
40 | org.slf4j
41 | slf4j-simple
42 |
43 |
44 |
45 |
46 |
47 | commons-logging
48 | commons-logging
49 | 1.2
50 |
51 |
52 |
53 | org.slf4j
54 | slf4j-api
55 | 1.7.12
56 |
57 |
58 |
59 | ch.qos.logback
60 | logback-classic
61 | 1.1.2
62 |
63 |
64 |
65 | ch.qos.logback
66 | logback-core
67 | 1.1.2
68 |
69 |
70 |
71 | org.apache.commons
72 | commons-lang3
73 | 3.4
74 |
75 |
76 |
77 | commons-io
78 | commons-io
79 | 2.4
80 |
81 |
82 |
83 | commons-codec
84 | commons-codec
85 | 1.10
86 |
87 |
88 |
89 | commons-dbutils
90 | commons-dbutils
91 | 1.6
92 |
93 |
94 |
95 | com.h2database
96 | h2
97 | 1.4.187
98 |
99 |
100 |
101 | junit
102 | junit
103 | 3.8.1
104 | test
105 |
106 |
107 |
108 | com.qianmi
109 | aliyun-java-sdk-ecs
110 | 2014-11-17
111 |
112 |
113 |
114 | com.eclipsesource.minimal-json
115 | minimal-json
116 | 0.9.2
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 | org.apache.maven.plugins
125 | maven-release-plugin
126 |
127 | ${git.username}
128 | ${git.password}
129 |
130 |
131 |
132 |
133 | org.apache.maven.plugins
134 | maven-compiler-plugin
135 | 3.2
136 |
137 | ${maven.compiler.source}
138 | ${maven.compiler.target}
139 | ${project.build.sourceEncoding}
140 |
141 |
142 |
143 |
144 | org.apache.maven.plugins
145 | maven-assembly-plugin
146 | 2.5.4
147 |
148 | false
149 |
150 |
151 | true
152 | com.qianmi.Bootstrap
153 |
154 |
155 |
156 | jar-with-dependencies
157 |
158 |
159 |
160 |
161 | assemble-all
162 | package
163 |
164 | single
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 | nexus repository
175 | intranet public groups
176 | http://nexus.dev.ofpay.com/nexus/content/groups/public
177 |
178 | false
179 |
180 |
181 |
182 |
183 |
--------------------------------------------------------------------------------
/src/main/java/com/qianmi/controller/WebController.java:
--------------------------------------------------------------------------------
1 | package com.qianmi.controller;
2 |
3 | import com.eclipsesource.json.JsonObject;
4 | import com.qianmi.DeployException;
5 | import com.qianmi.form.InstanceForm;
6 | import com.qianmi.form.InstanceResult;
7 | import com.qianmi.form.InstanceStatus;
8 | import com.qianmi.models.UserInstance;
9 | import com.qianmi.models.UserInstanceHelper;
10 | import com.qianmi.proxy.InstanceProxy;
11 | import com.qianmi.service.AliyunInstanceService;
12 | import org.apache.commons.codec.binary.Base64;
13 | import org.apache.commons.io.IOUtils;
14 | import org.apache.commons.lang3.StringUtils;
15 | import org.eclipse.jetty.http.HttpStatus;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | import java.io.IOException;
20 | import java.nio.charset.Charset;
21 |
22 | import static spark.Spark.*;
23 |
24 | public class WebController {
25 |
26 | protected final transient Logger logger = LoggerFactory.getLogger(getClass());
27 |
28 | public WebController() {
29 |
30 | get("/", (request, response) -> "Welcome Cloudeply!
");
31 |
32 | /**
33 | * 创建新主机
34 | * POST /host/new
35 | */
36 | post("/host/new", (request, response) -> {
37 | InstanceForm form = new InstanceForm();
38 | form.setUser(request.queryParams("user"));
39 | form.setPlatform(request.queryParams("platform"));
40 | form.setRegion(request.queryParams("region"));
41 | form.setOsName(StringUtils.defaultString(request.queryParams("osName"), "CentOS").toLowerCase());
42 | form.setOsBit(request.queryParams("osBit"));
43 | form.setOsVersion(request.queryParams("osVersion"));
44 | form.setCpu(request.queryParams("cpu"));
45 | form.setMemory(request.queryParams("memory"));
46 | form.setPassword(request.queryParams("password"));
47 | form.setInternetChargeType(request.queryParams("internetChargeType"));
48 | form.setInternetMaxBandwidthOut(request.queryParams("internetMaxBandwidthOut"));
49 | logger.debug("new host param:{}", form);
50 | JsonObject result2json = new JsonObject();
51 | // validate
52 | if (StringUtils.isEmpty(form.getUser())) {
53 | result2json.add("user", "is not empty");
54 | }
55 | if (form.getOsBit() != null && !StringUtils.isNumeric(form.getOsBit())) {
56 | result2json.add("osBit", "is not number");
57 | }
58 | if (form.getCpu() != null && !StringUtils.isNumeric(form.getCpu())) {
59 | result2json.add("cpu", "is not number");
60 | }
61 | if (form.getMemory() != null && !StringUtils.isNumeric(form.getMemory())) {
62 | result2json.add("memory", "is not number");
63 | }
64 | if (!result2json.isEmpty()) {
65 | response.status(HttpStatus.BAD_REQUEST_400);
66 | return result2json;
67 | }
68 |
69 | InstanceProxy instanceProxy = new InstanceProxy();
70 | try {
71 | InstanceResult r = instanceProxy.newInstance(form);
72 | // add user record
73 | UserInstance u = new UserInstance();
74 | u.setInstanceId(r.getInstanceId());
75 | u.setInstanceIp(r.getIp());
76 | u.setUser(form.getUser());
77 | u.setPlatform(form.getPlatform());
78 | UserInstanceHelper userInstanceHelper = new UserInstanceHelper();
79 | userInstanceHelper.add(u);
80 | return result2json.add("instanceId", r.getInstanceId()).add("ip", r.getIp());
81 | } catch (DeployException de) {
82 | response.status(HttpStatus.INTERNAL_SERVER_ERROR_500);
83 | return result2json.add("code", de.getCode()).add("message", de.getMessage());
84 | }
85 |
86 | });
87 |
88 | /**
89 | * 查询主机状态
90 | * GET /host/status
91 | * Param: instanceId
92 | *
93 | * json: {result: Running, Starting, Stopped}
94 | */
95 | get("/host/status", (request, response) -> {
96 | String instanceId = request.queryParams("instanceId");
97 | logger.debug("param instanceId:{}", instanceId);
98 | JsonObject result2json = new JsonObject();
99 | if (StringUtils.isEmpty(instanceId)) {
100 | response.status(HttpStatus.BAD_REQUEST_400);
101 | result2json.add("instanceId", "param is not empty");
102 | return result2json;
103 | }
104 |
105 | AliyunInstanceService instanceService = new AliyunInstanceService();
106 | try {
107 | InstanceStatus status = instanceService.describeInstanceAttribute(instanceId);
108 |
109 | return result2json.add("instanceId", status.getInstanceId())
110 | .add("status", status.getStatus())
111 | .add("publicIp", status.getPublicIp())
112 | .add("innerIp", status.getInnerIp());
113 | } catch (DeployException de) {
114 | response.status(HttpStatus.INTERNAL_SERVER_ERROR_500);
115 | return result2json.add("code", de.getCode()).add("message", de.getMessage());
116 | }
117 | });
118 |
119 | /**
120 | * 执行ansible命令
121 | * POST /ansible/send
122 | * Content-Type:application/x-www-form-urlencoded
123 | * Param: command
124 | *
125 | * Result:
126 | * responseStatus == 200:成功, 400:参数错误, 500:系统错误
127 | * responseBody
128 | */
129 | post("/ansible/send", (request, response) -> {
130 | JsonObject result2json = new JsonObject();
131 | String command = request.queryParams("command");
132 | logger.debug("command param:{}", command);
133 | if (StringUtils.isEmpty(command)) {
134 | response.status(HttpStatus.BAD_REQUEST_400);
135 | return result2json.add("command", "param is not empty");
136 | }
137 | command = StringUtils.toEncodedString(Base64.decodeBase64(command), Charset.defaultCharset());
138 | logger.debug("command decode:{}", command);
139 | ProcessBuilder pb = new ProcessBuilder();
140 | pb.command("/bin/sh", "-c", command);
141 | try {
142 | Process p = pb.start();
143 | String result = IOUtils.toString(p.getErrorStream(), Charset.defaultCharset());
144 | logger.info("command process:\n{}", result);
145 | return result2json.add("result", result);
146 | } catch (IOException ioe) {
147 | logger.error("command execute error", ioe);
148 | response.status(HttpStatus.INTERNAL_SERVER_ERROR_500);
149 | return result2json.add("error", ioe.getMessage());
150 | }
151 | });
152 |
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------