|
|
@@ -0,0 +1,247 @@
|
|
|
+package cn.reghao.devops.mgr.mgr.aliyun.service;
|
|
|
+
|
|
|
+import ch.qos.logback.classic.Level;
|
|
|
+import ch.qos.logback.classic.Logger;
|
|
|
+import ch.qos.logback.classic.LoggerContext;
|
|
|
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
|
|
|
+import cn.reghao.jutil.jdk.security.RsaCryptor;
|
|
|
+import cn.reghao.jutil.jdk.serializer.JsonConverter;
|
|
|
+import cn.reghao.jutil.jdk.shell.ShellExecutor;
|
|
|
+import cn.reghao.jutil.jdk.shell.ShellResult;
|
|
|
+import cn.reghao.jutil.jdk.thread.ThreadPoolWrapper;
|
|
|
+import com.aliyun.auth.credentials.Credential;
|
|
|
+import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
|
|
|
+import com.aliyun.sdk.service.cas20200407.models.*;
|
|
|
+import com.aliyun.sdk.service.cas20200407.*;
|
|
|
+import com.google.gson.Gson;
|
|
|
+import com.google.gson.JsonArray;
|
|
|
+import com.google.gson.JsonElement;
|
|
|
+import com.google.gson.JsonObject;
|
|
|
+import darabonba.core.client.ClientOverrideConfiguration;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2025-03-27 16:14:53
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+public class AliyunCertificate {
|
|
|
+ static ScheduledExecutorService scheduler = ThreadPoolWrapper.scheduledThreadPool("checker", 10);
|
|
|
+ static Map<Long, ScheduledFuture<?>> futureMap = new HashMap<>();
|
|
|
+
|
|
|
+ static void setLogLevel() {
|
|
|
+ LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
|
|
|
+ Logger rootLogger = loggerContext.getLogger("ROOT");
|
|
|
+ rootLogger.setLevel(Level.INFO);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) throws Exception {
|
|
|
+ setLogLevel();
|
|
|
+
|
|
|
+ StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
|
|
|
+ .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
|
|
|
+ .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
|
|
|
+ //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
|
|
|
+ .build());
|
|
|
+
|
|
|
+ // Endpoint 请参考 https://api.aliyun.com/product/cas
|
|
|
+ String endpoint = "cas.aliyuncs.com";
|
|
|
+ AsyncClient client = AsyncClient.builder()
|
|
|
+ .credentialsProvider(provider)
|
|
|
+ .overrideConfiguration(
|
|
|
+ ClientOverrideConfiguration.create()
|
|
|
+ .setEndpointOverride(endpoint)
|
|
|
+ )
|
|
|
+ .build();
|
|
|
+
|
|
|
+ String orderType = "";
|
|
|
+ //orderType = "CERT";
|
|
|
+ listUserCertificateOrder(client, orderType);
|
|
|
+ log.info("main-thread goto sleep...");
|
|
|
+ Thread.sleep(3600_000);
|
|
|
+
|
|
|
+ //createCertificate(client);
|
|
|
+ long orderId = 13588158L;
|
|
|
+ //describeCertificateState(client, orderId);
|
|
|
+ // Finally, close the client
|
|
|
+ client.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ static void listUserCertificateOrder(AsyncClient client, String orderType) throws Exception {
|
|
|
+ ListUserCertificateOrderRequest listUserCertificateOrderRequest;
|
|
|
+ if (orderType.isBlank()) {
|
|
|
+ listUserCertificateOrderRequest = ListUserCertificateOrderRequest.builder()
|
|
|
+ .build();
|
|
|
+ } else {
|
|
|
+ listUserCertificateOrderRequest = ListUserCertificateOrderRequest.builder()
|
|
|
+ .orderType(orderType)
|
|
|
+ .build();
|
|
|
+ }
|
|
|
+
|
|
|
+ CompletableFuture<ListUserCertificateOrderResponse> response = client.listUserCertificateOrder(listUserCertificateOrderRequest);
|
|
|
+ ListUserCertificateOrderResponse resp = response.get();
|
|
|
+ String jsonData = new Gson().toJson(resp);
|
|
|
+ JsonObject jsonObject = JsonConverter.jsonToObject(jsonData, JsonObject.class);
|
|
|
+ JsonArray jsonArray = jsonObject.get("body").getAsJsonObject().get("certificateOrderList").getAsJsonArray();
|
|
|
+ for (JsonElement jsonElement : jsonArray) {
|
|
|
+ JsonObject jsonObject1 = jsonElement.getAsJsonObject();
|
|
|
+ if (orderType.isBlank()) {
|
|
|
+ long orderId = jsonObject1.get("orderId").getAsLong();
|
|
|
+ describeCertificateState(client, orderId);
|
|
|
+
|
|
|
+ /*String domain = jsonObject1.get("domain").getAsString();
|
|
|
+ long endTimeMs = jsonObject1.get("certEndTime").getAsLong();
|
|
|
+ LocalDateTime expireDateTime = DateTimeConverter.localDateTime(endTimeMs);*/
|
|
|
+ } else {
|
|
|
+ long certificateId = jsonObject1.get("certificateId").getAsLong();
|
|
|
+ getUserCertificateDetail(client, certificateId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void getUserCertificateDetail(AsyncClient client, long certificateId) throws Exception {
|
|
|
+ GetUserCertificateDetailRequest getUserCertificateDetailRequest = GetUserCertificateDetailRequest.builder()
|
|
|
+ .certId(certificateId)
|
|
|
+ .certFilter(false)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ CompletableFuture<GetUserCertificateDetailResponse> response = client.getUserCertificateDetail(getUserCertificateDetailRequest);
|
|
|
+ GetUserCertificateDetailResponse resp = response.get();
|
|
|
+ String jsonData = new Gson().toJson(resp);
|
|
|
+ JsonObject jsonObject = JsonConverter.jsonToObject(jsonData, JsonObject.class);
|
|
|
+ JsonObject certDetail = jsonObject.get("body").getAsJsonObject();
|
|
|
+ String domain = certDetail.get("sans").getAsString();
|
|
|
+ String certificate = certDetail.get("cert").getAsString();
|
|
|
+ String privateKey = certDetail.get("key").getAsString();
|
|
|
+ long notBefore = certDetail.get("notBefore").getAsLong();
|
|
|
+ long notAfter = certDetail.get("notAfter").getAsLong();
|
|
|
+ LocalDateTime expireDateTime = DateTimeConverter.localDateTime(notAfter);
|
|
|
+
|
|
|
+ String certPath = String.format("/home/reghao/Downloads/1/%s.pem", domain);
|
|
|
+ File certFile = new File(certPath);
|
|
|
+ if (!certFile.exists()) {
|
|
|
+ RsaCryptor.savePemFile(certificate, certPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ String keyPath = String.format("/home/reghao/Downloads/1/%s.key", domain);;
|
|
|
+ File keyFile = new File(keyPath);
|
|
|
+ if (!keyFile.exists()) {
|
|
|
+ RsaCryptor.savePemFile(privateKey, keyPath);
|
|
|
+ }
|
|
|
+ System.out.println();
|
|
|
+ }
|
|
|
+
|
|
|
+ static void createCertificates(AsyncClient client) throws Exception {
|
|
|
+ List<String> domainList = List.of("tnb.reghao.cn", "api.reghao.cn", "oss.reghao.cn", "bnt.reghao.cn");
|
|
|
+ List<String> domainList1 = List.of("blog.reghao.cn", "git.reghao.cn", "docker.reghao.cn");
|
|
|
+ for (String domain : domainList) {
|
|
|
+ createCertificate(client, domain);
|
|
|
+ Thread.sleep(5_000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void createCertificate(AsyncClient client, String domain) throws ExecutionException, InterruptedException {
|
|
|
+ CreateCertificateRequestRequest createCertificateRequestRequest = CreateCertificateRequestRequest.builder()
|
|
|
+ .productCode("digicert-free-1-free")
|
|
|
+ .username("赵梓潼")
|
|
|
+ .phone("18782243510")
|
|
|
+ .email("lhao.sg@qq.com")
|
|
|
+ .domain(domain)
|
|
|
+ .validateType("DNS")
|
|
|
+ .build();
|
|
|
+
|
|
|
+ CompletableFuture<CreateCertificateRequestResponse> response = client.createCertificateRequest(createCertificateRequestRequest);
|
|
|
+ CreateCertificateRequestResponse resp = response.get();
|
|
|
+ String jsonData = new Gson().toJson(resp);
|
|
|
+ JsonObject jsonObject = JsonConverter.jsonToObject(jsonData, JsonObject.class);
|
|
|
+ JsonObject respBody = jsonObject.get("body").getAsJsonObject();
|
|
|
+ long orderId = respBody.get("orderId").getAsLong();
|
|
|
+ log.info("orderId -> {}", orderId);
|
|
|
+ }
|
|
|
+
|
|
|
+ static void describeCertificateState(AsyncClient client, long orderId) throws ExecutionException, InterruptedException {
|
|
|
+ DescribeCertificateStateRequest describeCertificateStateRequest = DescribeCertificateStateRequest.builder()
|
|
|
+ .orderId(orderId)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ CompletableFuture<DescribeCertificateStateResponse> response = client.describeCertificateState(describeCertificateStateRequest);
|
|
|
+ DescribeCertificateStateResponse resp = response.get();
|
|
|
+ String jsonData = new Gson().toJson(resp);
|
|
|
+ JsonObject jsonObject = JsonConverter.jsonToObject(jsonData, JsonObject.class);
|
|
|
+ JsonObject respBody = jsonObject.get("body").getAsJsonObject();
|
|
|
+ String type = respBody.get("type").getAsString();
|
|
|
+ if ("certificate".equals(type)) {
|
|
|
+ String certificate = respBody.get("certificate").getAsString();
|
|
|
+ String privateKey = respBody.get("privateKey").getAsString();
|
|
|
+ } else if ("domain_verify".equals(type)) {
|
|
|
+ String recordDomain = respBody.get("recordDomain").getAsString();
|
|
|
+ String recordType = respBody.get("recordType").getAsString();
|
|
|
+ String recordValue = respBody.get("recordValue").getAsString();
|
|
|
+ String domain = recordDomain.replace("_dnsauth.", "");
|
|
|
+ // 添加 TXT 记录
|
|
|
+ AliyunDns.addTxtRecord(domain, recordDomain, recordValue);
|
|
|
+
|
|
|
+ CheckTask checkTask = new CheckTask(client, domain, orderId);
|
|
|
+ ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(checkTask, 60, 60, TimeUnit.SECONDS);
|
|
|
+ futureMap.put(orderId, future);
|
|
|
+ Thread.sleep(5_000);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static class CheckTask implements Runnable {
|
|
|
+ private final AsyncClient client;
|
|
|
+ private final String domain;
|
|
|
+ private final long orderId;
|
|
|
+
|
|
|
+ public CheckTask(AsyncClient client, String domain, long orderId) {
|
|
|
+ this.client = client;
|
|
|
+ this.domain = domain;
|
|
|
+ this.orderId = orderId;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void run() {
|
|
|
+ try {
|
|
|
+ DescribeCertificateStateRequest describeCertificateStateRequest = DescribeCertificateStateRequest.builder()
|
|
|
+ .orderId(orderId)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ CompletableFuture<DescribeCertificateStateResponse> response = client.describeCertificateState(describeCertificateStateRequest);
|
|
|
+ DescribeCertificateStateResponse resp = response.get();
|
|
|
+ String jsonData = new Gson().toJson(resp);
|
|
|
+ JsonObject jsonObject = JsonConverter.jsonToObject(jsonData, JsonObject.class);
|
|
|
+ JsonObject respBody = jsonObject.get("body").getAsJsonObject();
|
|
|
+ String type = respBody.get("type").getAsString();
|
|
|
+ if ("certificate".equals(type)) {
|
|
|
+ String certificate = respBody.get("certificate").getAsString();
|
|
|
+ String privateKey = respBody.get("privateKey").getAsString();
|
|
|
+ ScheduledFuture<?> future = futureMap.get(orderId);
|
|
|
+ if (future != null) {
|
|
|
+ log.info("{} - {} 证书已签发, 取消定时任务...", domain, orderId);
|
|
|
+ future.cancel(true);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ log.info("{} - {} 证书状态 {}...", domain, orderId, type);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ static void reloadNginx() {
|
|
|
+ ShellExecutor shellExecutor = new ShellExecutor();
|
|
|
+ String cmd = "/usr/bin/nginx -t";
|
|
|
+ String cmd1 = "/usr/bin/nginx -s reload";
|
|
|
+ ShellResult shellResult = shellExecutor.exec(cmd.split("\\s+"));
|
|
|
+ String result = shellResult.getResult();
|
|
|
+ System.out.println(result);
|
|
|
+ }
|
|
|
+}
|