diff --git a/pom.xml b/pom.xml index bb7e61a..5096e39 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,12 @@ spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-test + + + cn.hutool hutool-all diff --git a/src/main/java/net/educoder/controller/CloudController.java b/src/main/java/net/educoder/controller/CloudController.java index b0ebd1b..bfcf5ea 100644 --- a/src/main/java/net/educoder/controller/CloudController.java +++ b/src/main/java/net/educoder/controller/CloudController.java @@ -1,7 +1,8 @@ package net.educoder.controller; import lombok.extern.slf4j.Slf4j; -import net.educoder.CloudHostService; +import net.educoder.model.param.ResetCloudHostParam; +import net.educoder.service.CloudHostService; import net.educoder.model.dto.CreateCloudHostDto; import net.educoder.util.ResponseResult; import org.springframework.beans.factory.annotation.Autowired; @@ -54,9 +55,9 @@ public class CloudController { * @return */ @PostMapping("/resetCloudHost") - public ResponseResult resetCloudHost(String serverId) { + public ResponseResult resetCloudHost(ResetCloudHostParam resetCloudHostParam) { - boolean status = cloudHostService.resetCloudHost(serverId); + boolean status = cloudHostService.resetCloudHost(resetCloudHostParam); if (!status) { return ResponseResult.failed(-1, "重置云主机失败"); } diff --git a/src/main/java/net/educoder/model/param/ResetCloudHostParam.java b/src/main/java/net/educoder/model/param/ResetCloudHostParam.java new file mode 100644 index 0000000..84505db --- /dev/null +++ b/src/main/java/net/educoder/model/param/ResetCloudHostParam.java @@ -0,0 +1,36 @@ +package net.educoder.model.param; + +import lombok.Data; + +/** + * @Author: youys + * @Date: 2022/8/19 + * @Description: + */ +@Data +public class ResetCloudHostParam { + + /** + * 云主机id + */ + private String serverId; + + /** + * 用户名 + */ + private String username; + /** + * 密码 + */ + private String password; + /** + * 端口 + */ + private int port; + + /** + * 浮动id + */ + private String floatingIp; + +} diff --git a/src/main/java/net/educoder/CloudHostService.java b/src/main/java/net/educoder/service/CloudHostService.java similarity index 63% rename from src/main/java/net/educoder/CloudHostService.java rename to src/main/java/net/educoder/service/CloudHostService.java index 5c80000..d615901 100644 --- a/src/main/java/net/educoder/CloudHostService.java +++ b/src/main/java/net/educoder/service/CloudHostService.java @@ -1,11 +1,11 @@ -package net.educoder; +package net.educoder.service; import cn.hutool.core.util.RandomUtil; import com.google.common.cache.Cache; import lombok.extern.slf4j.Slf4j; import net.educoder.constant.CommonConstants; -import net.educoder.model.ShellResult; import net.educoder.model.dto.CreateCloudHostDto; +import net.educoder.model.param.ResetCloudHostParam; import net.educoder.util.JCloudUtil; import net.educoder.util.ShellUtil; import org.apache.commons.lang3.StringUtils; @@ -14,6 +14,10 @@ import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + /** * @Author: youys @@ -39,10 +43,21 @@ public class CloudHostService { @Value("${jcloud.frpc.host}") private String frpcHost; + @Value("${jcloud.networkIds}") + private String networkIds; + @Autowired @Qualifier("guavaCache") private Cache guavaCache; + + private Object lock = new Object(); + private Object networkLock = new Object(); + + private int index = 0; + + private List networkIdList; + /** * 创建云主机 * 1、创建云主机 @@ -58,18 +73,9 @@ public class CloudHostService { apiToken = refreshApiToken(); } // 创建云主机 - CreateCloudHostDto createCloudHostDto = JCloudUtil.oneStepCreateCloudHost(apiToken, imageId); + CreateCloudHostDto createCloudHostDto = JCloudUtil.oneStepCreateCloudHost(apiToken, imageId, nextNetworkId()); - String template = frpcTemplate.replaceAll("\\{param1}", frpcHost).replaceAll("\\{param2}", String.valueOf(port)); - - // 通过浮动ip+port 连接ssh执行脚本 - String command = StringUtils.join("sshpass -p ", createCloudHostDto.getPassword(), " ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ", - createCloudHostDto.getUsername(), "@", createCloudHostDto.getFloatingIp(), " \'", - "cd /root/frp_0.44.0_linux_amd64; sudo echo -e \"", template, "\" > frpc.ini ; cat frpc.ini; nohup ./frpc >& cataline.log 2>&1 &", "\'"); - String uuid = RandomUtil.randomString(16); - log.info("id{},配置内网穿透命令:{}", uuid, command); - String execResult = ShellUtil.execute(command); - log.info("id{},执行结果:{}", uuid, execResult); + intranetThrough(port, createCloudHostDto.getUsername(), createCloudHostDto.getPassword(), createCloudHostDto.getFloatingIp()); createCloudHostDto.setPort(port); createCloudHostDto.setIp(frpcHost); @@ -94,15 +100,21 @@ public class CloudHostService { /** * 重置云主机 * - * @param serverId + * @param resetCloudHostParam * @return */ - public boolean resetCloudHost(String serverId) { + public boolean resetCloudHost(ResetCloudHostParam resetCloudHostParam) { String apiToken = guavaCache.getIfPresent(CommonConstants.API_TOKEN); if (StringUtils.isBlank(apiToken)) { apiToken = refreshApiToken(); } - return JCloudUtil.rebuildCloud(apiToken, serverId); + + boolean status = JCloudUtil.rebuildCloud(apiToken, resetCloudHostParam.getServerId()); + if (status) { + // 重置之后需要重新配置内网穿透 + intranetThrough(resetCloudHostParam.getPort(), resetCloudHostParam.getUsername(), resetCloudHostParam.getPassword(), resetCloudHostParam.getFloatingIp()); + } + return status; } /** @@ -133,5 +145,49 @@ public class CloudHostService { return apiToken; } + /** + * 内网穿透 + * + * @param port + * @param username + * @param password + * @param floatingIp + */ + private void intranetThrough(int port, String username, String password, String floatingIp) { + String template = frpcTemplate.replaceAll("\\{param1}", frpcHost).replaceAll("\\{param2}", String.valueOf(port)); + + // 通过浮动ip+port 连接ssh执行脚本 + String command = StringUtils.join("sshpass -p ", password, " ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ", + username, "@", floatingIp, " \'", + "cd /root/frp_0.44.0_linux_amd64; sudo echo -e \"", template, "\" > frpc.ini ; cat frpc.ini; nohup ./frpc >& cataline.log 2>&1 &", "\'"); + String uuid = RandomUtil.randomString(16); + log.info("id{},配置内网穿透命令:{}", uuid, command); + String execResult = ShellUtil.execute(command); + log.info("id{},执行结果:{}", uuid, execResult); + } + + /** + * 获取一个网络id + * + * @return + */ + public String nextNetworkId() { + + if (networkIdList == null) { + synchronized (networkLock) { + if (networkIdList == null) { + String[] split = networkIds.split(";"); + networkIdList = new ArrayList(split.length); + networkIdList.addAll(Arrays.asList(split)); + } + } + } + synchronized (lock) { + if (index + 1 > networkIdList.size()) { + index = 0; + } + return networkIdList.get(index++); + } + } } diff --git a/src/main/java/net/educoder/util/JCloudUtil.java b/src/main/java/net/educoder/util/JCloudUtil.java index 5365b82..4c7c686 100644 --- a/src/main/java/net/educoder/util/JCloudUtil.java +++ b/src/main/java/net/educoder/util/JCloudUtil.java @@ -317,9 +317,9 @@ public class JCloudUtil { * * @param apiToken */ - public static CreateCloudHostDto oneStepCreateCloudHost(String apiToken, String imageId) { + public static CreateCloudHostDto oneStepCreateCloudHost(String apiToken, String imageId, String networkId) { // 创建云主机 - String createCloudHost = createCloudHost(apiToken, defaultCreateCloudHostParam(imageId)); + String createCloudHost = createCloudHost(apiToken, defaultCreateCloudHostParam(imageId, networkId)); // 获取serverId String serverId = JSONObject.parseObject(createCloudHost).getJSONObject("server").getString("id"); @@ -401,16 +401,18 @@ public class JCloudUtil { * 规格:4核8G * 内网网络:提前创建好 * + * @param imageId 镜像id + * @param networkId 网络id * @return */ - public static CreateCloudHostParam defaultCreateCloudHostParam(String imageId) { + public static CreateCloudHostParam defaultCreateCloudHostParam(String imageId, String networkId) { CreateCloudHostParam createCloudHost = new CreateCloudHostParam(); createCloudHost.setName(RandomUtil.randomString(10)); // 镜像id createCloudHost.setImageRef(imageId); createCloudHost.setFlavorRef("02723f5f-5518-4031-bd5e-dfecae675606"); // 网络id - createCloudHost.setNetworkId("f41ece4b-ff14-4444-8d1d-c730779a0df2"); + createCloudHost.setNetworkId(networkId); return createCloudHost; } @@ -464,7 +466,7 @@ public class JCloudUtil { String serverId = "532773ed-c022-458e-85f3-f45649b08096"; String floatingIpId = "8adc22ff-9cbd-447d-bcdc-2c45014f651a"; - oneStepDestroyCloudHost(apiToken, serverId,floatingIpId); + oneStepDestroyCloudHost(apiToken, serverId, floatingIpId); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 8ed877a..6b3d359 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -11,3 +11,8 @@ jcloud: frpc: host: 39.104.50.181 template: "[common]\nserver_addr = {param1}\nserver_port = 7000\n[ssh{param2}]\ntype = tcp\nlocal_ip = 127.0.0.1\nlocal_port = 22\nremote_port = {param2}" + networkIds: "f41ece4b-ff14-4444-8d1d-c730779a0df2; + d393c438-d0e1-4489-9642-e3d32db7e704;b4e26904-c9b9-4620-bd94-1945562d535e; + 0dc4f41b-7e13-4e9d-b771-252c4ea5d851;8958554d-0fc3-4c8c-a288-69fc6e06cd13; + 3b598368-0f93-430e-9dec-c73f2930fddc;284f9866-0d6b-4306-a7fe-177afaac18c5; + b7204f48-06be-4216-83da-f631711fd3c9;3302992e-0143-4e06-9d11-78abe8881c5f;" diff --git a/src/test/java/net/educoder/CacheTest.java b/src/test/java/net/educoder/CacheTest.java new file mode 100644 index 0000000..5a81ff3 --- /dev/null +++ b/src/test/java/net/educoder/CacheTest.java @@ -0,0 +1,38 @@ +package net.educoder; + +import com.google.common.cache.Cache; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + + +/** + * @Author: youys + * @Date: 2022/8/19 + * @Description: + */ + +@SpringBootTest +public class CacheTest { + + @Autowired + private Cache cache; + + + @Test + public void testCacheExpire() throws Exception { + + + cache.put("key","value"); + + int i=15; + while(i-- > 0){ + System.out.println(cache.getIfPresent("key")); + Thread.sleep(1000); + } + + System.out.println("finish"); + + } + +}