mirror of
https://github.com/certd/certd.git
synced 2026-07-27 14:57:40 +08:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8cbca5761e | |||
| 967846bef5 | |||
| 18b2d3ac20 | |||
| 7d22fe3d7d | |||
| ee67b6c042 | |||
| 1cfa76683b | |||
| 4662e45e58 | |||
| 1fefbdc9ab | |||
| 1cb2a57c55 |
@@ -3,6 +3,16 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.42.6](https://github.com/certd/certd/compare/v1.42.5...v1.42.6) (2026-07-18)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 修复正常批量删除流水线报权限不足的bug ([5b50083](https://github.com/certd/certd/commit/5b500830a122c6c42dab054e57fed509050f94da))
|
||||||
|
|
||||||
|
### Performance Improvements
|
||||||
|
|
||||||
|
* 优化动态加载依赖镜像地址,多次重试 ([5f53b81](https://github.com/certd/certd/commit/5f53b81c75dd242b4260ac08cae14c6d1a08a883))
|
||||||
|
|
||||||
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
## [1.42.5](https://github.com/certd/certd/compare/v1.42.4...v1.42.5) (2026-07-15)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -75,5 +75,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,5 +54,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,5 +51,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -568,11 +568,18 @@ export class RuntimeDepsService {
|
|||||||
const result = await this.commandRunner.run(command, args, { cwd: rootDir, timeoutMs: this.installTimeoutMs, env: tryEnv });
|
const result = await this.commandRunner.run(command, args, { cwd: rootDir, timeoutMs: this.installTimeoutMs, env: tryEnv });
|
||||||
if (result.code === 0) {
|
if (result.code === 0) {
|
||||||
this.writeInstallState(statePath, { installedAt: new Date().toISOString(), registryUrl: tryUrl, dependenciesHash, nodeVersion: process.version, pnpmVersion, lockFileExists: fs.existsSync(lockPath) });
|
this.writeInstallState(statePath, { installedAt: new Date().toISOString(), registryUrl: tryUrl, dependenciesHash, nodeVersion: process.version, pnpmVersion, lockFileExists: fs.existsSync(lockPath) });
|
||||||
|
log.info(`${result.stdout?.slice(-2000) || "无npm安装日志输出"}`);
|
||||||
log.info("第三方依赖安装完成");
|
log.info("第三方依赖安装完成");
|
||||||
return { registryUrl: tryUrl, packageJsonPath };
|
return { registryUrl: tryUrl, packageJsonPath };
|
||||||
}
|
}
|
||||||
lastError = result.stderr || result.stdout || "unknown error";
|
const errOutput = (result.stderr || "").trim();
|
||||||
log.warn?.(`镜像 ${tryUrl || "默认"} 安装失败${urlsToTry.length > 1 ? ",尝试下一个镜像..." : ""}`);
|
const outOutput = (result.stdout || "").trim();
|
||||||
|
lastError = errOutput || outOutput || "unknown error";
|
||||||
|
log.info(`镜像 ${tryUrl || "默认"} 安装失败,退出码: ${result.code}${urlsToTry.length > 1 ? ",尝试下一个镜像..." : ""}`);
|
||||||
|
log.info(` pnpm stderr: ${(errOutput || "无npm安装日志输出").slice(-2000)}`);
|
||||||
|
if (outOutput) {
|
||||||
|
log.info(` pnpm stdout: ${outOutput.slice(-2000)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.writeInstallState(statePath, {
|
this.writeInstallState(statePath, {
|
||||||
...currentState,
|
...currentState,
|
||||||
|
|||||||
@@ -31,5 +31,5 @@
|
|||||||
"prettier": "3.3.3",
|
"prettier": "3.3.3",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,5 +37,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,5 +63,5 @@
|
|||||||
"fetch"
|
"fetch"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,5 +38,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,5 +69,5 @@
|
|||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,5 +52,5 @@
|
|||||||
"typeorm": "^0.3.20",
|
"typeorm": "^0.3.20",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,19 +93,21 @@ export class Flyway {
|
|||||||
await queryRunner.commitTransaction();
|
await queryRunner.commitTransaction();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(err);
|
this.logger.error(err);
|
||||||
|
this.errorTip(err);
|
||||||
await this.storeSqlExecLog(file.script, filepath, false, queryRunner);
|
await this.storeSqlExecLog(file.script, filepath, false, queryRunner);
|
||||||
await queryRunner.rollbackTransaction();
|
await queryRunner.rollbackTransaction();
|
||||||
|
|
||||||
if (err.code === "SQLITE_IOERR_WRITE") {
|
|
||||||
this.logger.warn("SQLite数据库写入失败,可能您的操作系统版本太低,请将「certd:latest」镜像改为「certd:slim」即可。(如需指定版本可以修改成「certd:[version]-slim」)", file.script);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.logger.info("[ midfly ] end-------------");
|
this.logger.info("[ midfly ] end-------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private errorTip(err: any) {
|
||||||
|
if (err.code === "SQLITE_IOERR_WRITE") {
|
||||||
|
this.logger.warn("SQLite数据库写入失败,可能您的操作系统版本太低,请将「certd:latest」镜像改为「certd:slim」即可。(如需指定版本可以修改成「certd:[version]-slim」)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async storeSqlExecLog(filename: string, filepath: string, success: boolean, queryRunner: QueryRunner) {
|
private async storeSqlExecLog(filename: string, filepath: string, success: boolean, queryRunner: QueryRunner) {
|
||||||
const hash = await this.getFileHash(filepath);
|
const hash = await this.getFileHash(filepath);
|
||||||
//先删除
|
//先删除
|
||||||
@@ -265,6 +267,7 @@ export class Flyway {
|
|||||||
await queryRunner.query(sql);
|
await queryRunner.query(sql);
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
this.logger.error("exec sql error : ", err.message, err);
|
this.logger.error("exec sql error : ", err.message, err);
|
||||||
|
this.errorTip(err);
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,5 +38,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,5 +45,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "83495b32138cf831b4ea02054d12981d9787ebf0"
|
"gitHead": "246ee83015bf5589adc2a5fa3d1388c8d9a2a252"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import crypto from "node:crypto";
|
import crypto from "node:crypto";
|
||||||
import { BaotaAccess } from "../access.js";
|
import { BaotaAccess } from "../access.js";
|
||||||
import { HttpClient, HttpRequestConfig } from "@certd/basic";
|
import { HttpClient, HttpRequestConfig, ILogger } from "@certd/basic";
|
||||||
import * as querystring from "node:querystring";
|
import * as querystring from "node:querystring";
|
||||||
|
|
||||||
export class BaotaClient {
|
export class BaotaClient {
|
||||||
access: BaotaAccess;
|
access: BaotaAccess;
|
||||||
http: HttpClient;
|
http: HttpClient;
|
||||||
|
logger: ILogger
|
||||||
|
|
||||||
constructor(access: BaotaAccess, http: HttpClient) {
|
constructor(access: BaotaAccess, http: HttpClient) {
|
||||||
this.access = access;
|
this.access = access;
|
||||||
this.http = http;
|
this.http = http;
|
||||||
|
this.logger = access.ctx.logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
//将以上 java代码 翻译成nodejs 代码
|
//将以上 java代码 翻译成nodejs 代码
|
||||||
|
|||||||
+29
-18
@@ -88,7 +88,7 @@ export class BaotaDeployWebSiteCert extends AbstractTaskPlugin {
|
|||||||
})
|
})
|
||||||
siteName!: string | string[];
|
siteName!: string | string[];
|
||||||
|
|
||||||
async onInstance() {}
|
async onInstance() { }
|
||||||
async execute(): Promise<void> {
|
async execute(): Promise<void> {
|
||||||
const { cert, accessId } = this;
|
const { cert, accessId } = this;
|
||||||
const access = await this.getAccess(accessId);
|
const access = await this.getAccess(accessId);
|
||||||
@@ -104,26 +104,37 @@ export class BaotaDeployWebSiteCert extends AbstractTaskPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const lockKey = `baota-lock-${accessId}`;
|
const lockKey = `baota-lock-${accessId}`;
|
||||||
|
if (this.isDockerSite) {
|
||||||
|
this.logger.info(`当前已勾选docker站点(如果部署失败,请确认站点:${siteNames}, 是否全部为docker站点)`);
|
||||||
|
}
|
||||||
for (const site of siteNames) {
|
for (const site of siteNames) {
|
||||||
// 加锁,防止并发部署证书, 宝塔并发部署会导致nginx的conf错乱
|
// 加锁,防止并发部署证书, 宝塔并发部署会导致nginx的conf错乱
|
||||||
await this.ctx.utils.locker.execute(lockKey, async () => {
|
await this.ctx.utils.locker.execute(lockKey, async () => {
|
||||||
this.logger.info(`为站点:${site}设置证书,目前支持宝塔网站站点、docker站点`);
|
try {
|
||||||
if (this.isDockerSite) {
|
if (this.isDockerSite) {
|
||||||
const res = await client.doRequest("/mod/docker/com/set_ssl", "", {
|
this.logger.info(`为Docker站点:${site} 设置证书`);
|
||||||
site_name: site,
|
const res = await client.doRequest("/mod/docker/com/set_ssl", "", {
|
||||||
key: cert.key,
|
site_name: site,
|
||||||
csr: cert.crt,
|
key: cert.key,
|
||||||
});
|
csr: cert.crt,
|
||||||
this.logger.info(res?.msg);
|
});
|
||||||
} else {
|
this.logger.info(res?.msg);
|
||||||
const res = await client.doRequest("/site", "SetSSL", {
|
} else {
|
||||||
type: 0,
|
this.logger.info(`为非Docker站点:${site} 设置证书`);
|
||||||
siteName: site,
|
const res = await client.doRequest("/site", "SetSSL", {
|
||||||
key: cert.key,
|
type: 0,
|
||||||
csr: cert.crt,
|
siteName: site,
|
||||||
});
|
key: cert.key,
|
||||||
this.logger.info(res?.msg);
|
csr: cert.crt,
|
||||||
|
});
|
||||||
|
this.logger.info(res?.msg);
|
||||||
|
}
|
||||||
|
} catch (e: any) {
|
||||||
|
if (e?.message?.includes("没有服务器配置文件")) {
|
||||||
|
this.logger.error(e.message);
|
||||||
|
this.logger.warn(`首先请确认站点 ${site} 是否存在,如果存在,请到宝塔上手动保存一下该站点证书试试`);
|
||||||
|
}
|
||||||
|
throw e
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+111
@@ -0,0 +1,111 @@
|
|||||||
|
/// <reference types="mocha" />
|
||||||
|
|
||||||
|
import assert from "node:assert/strict";
|
||||||
|
import { DeployCertToTencentCLB } from "./index.js";
|
||||||
|
|
||||||
|
describe("DeployCertToTencentCLB", () => {
|
||||||
|
it("uses remote single-select inputs for CLB and HTTPS listener", () => {
|
||||||
|
const input = (DeployCertToTencentCLB as any).define.input;
|
||||||
|
|
||||||
|
assert.equal(input.loadBalancerId.component.name, "remote-select");
|
||||||
|
assert.equal(input.loadBalancerId.component.single, true);
|
||||||
|
assert.equal(input.loadBalancerId.component.action, "onGetCLBList");
|
||||||
|
assert.equal(input.loadBalancerId.required, true);
|
||||||
|
|
||||||
|
assert.equal(input.listenerId.component.name, "remote-select");
|
||||||
|
assert.equal(input.listenerId.component.single, true);
|
||||||
|
assert.equal(input.listenerId.component.action, "onGetListenerList");
|
||||||
|
assert.deepEqual(input.listenerId.component.watches, ["certDomains", "accessId", "region", "loadBalancerId"]);
|
||||||
|
assert.equal(input.listenerId.required, true);
|
||||||
|
|
||||||
|
assert.equal(input.domain.component.name, "remote-select");
|
||||||
|
assert.equal(input.domain.component.single, false);
|
||||||
|
assert.equal(input.domain.component.action, "onGetDomainList");
|
||||||
|
assert.deepEqual(input.domain.component.watches, ["certDomains", "accessId", "region", "loadBalancerId", "listenerId"]);
|
||||||
|
assert.equal(input.domain.required, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps CLB API results to remote-select options", async () => {
|
||||||
|
const plugin = new DeployCertToTencentCLB();
|
||||||
|
plugin.accessId = "access-1";
|
||||||
|
plugin.logger = { info: () => undefined } as any;
|
||||||
|
(plugin as any).getClient = async () => ({});
|
||||||
|
(plugin as any).getCLBList = async () => [
|
||||||
|
{
|
||||||
|
LoadBalancerId: "lb-1",
|
||||||
|
LoadBalancerName: "业务负载均衡",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const options = await plugin.onGetCLBList({});
|
||||||
|
|
||||||
|
assert.deepEqual(options, [
|
||||||
|
{
|
||||||
|
value: "lb-1",
|
||||||
|
label: "业务负载均衡<lb-1>",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps HTTPS listener API results after selecting a CLB", async () => {
|
||||||
|
const plugin = new DeployCertToTencentCLB();
|
||||||
|
plugin.accessId = "access-1";
|
||||||
|
plugin.loadBalancerId = "lb-1";
|
||||||
|
plugin.logger = { info: () => undefined } as any;
|
||||||
|
(plugin as any).getClient = async () => ({});
|
||||||
|
(plugin as any).getListenerList = async (_client: any, loadBalancerId: string, listenerIds: any) => {
|
||||||
|
assert.equal(loadBalancerId, "lb-1");
|
||||||
|
assert.equal(listenerIds, null);
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
ListenerId: "listener-1",
|
||||||
|
ListenerName: "HTTPS监听器",
|
||||||
|
Port: 443,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = await plugin.onGetListenerList({});
|
||||||
|
|
||||||
|
assert.deepEqual(options, [
|
||||||
|
{
|
||||||
|
value: "listener-1",
|
||||||
|
label: "HTTPS监听器:443<listener-1>",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("maps SNI domains from the selected listener rules", async () => {
|
||||||
|
const plugin = new DeployCertToTencentCLB();
|
||||||
|
plugin.accessId = "access-1";
|
||||||
|
plugin.loadBalancerId = "lb-1";
|
||||||
|
plugin.listenerId = "listener-1";
|
||||||
|
plugin.logger = { info: () => undefined } as any;
|
||||||
|
(plugin as any).getClient = async () => ({});
|
||||||
|
(plugin as any).getListenerList = async (_client: any, loadBalancerId: string, listenerIds: string[]) => {
|
||||||
|
assert.equal(loadBalancerId, "lb-1");
|
||||||
|
assert.deepEqual(listenerIds, ["listener-1"]);
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
ListenerId: "listener-1",
|
||||||
|
Rules: [{ Domain: "www.example.com" }, { Domain: "api.example.com" }],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const options = await plugin.onGetDomainList({});
|
||||||
|
|
||||||
|
assert.deepEqual(options, [
|
||||||
|
{
|
||||||
|
value: "www.example.com",
|
||||||
|
label: "www.example.com",
|
||||||
|
domain: "www.example.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "api.example.com",
|
||||||
|
label: "api.example.com",
|
||||||
|
domain: "api.example.com",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
+108
-20
@@ -1,7 +1,8 @@
|
|||||||
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
import { AbstractTaskPlugin, IsTaskPlugin, PageSearch, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { TencentAccess } from "../../../plugin-lib/tencent/index.js";
|
import { TencentAccess } from "../../../plugin-lib/tencent/index.js";
|
||||||
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
import { CertApplyPluginNames, CertInfo } from "@certd/plugin-cert";
|
||||||
|
import { createRemoteSelectInputDefine } from "@certd/plugin-lib";
|
||||||
@IsTaskPlugin({
|
@IsTaskPlugin({
|
||||||
name: "DeployCertToTencentCLB",
|
name: "DeployCertToTencentCLB",
|
||||||
title: "腾讯云-部署到CLB",
|
title: "腾讯云-部署到CLB",
|
||||||
@@ -73,29 +74,44 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
|
|||||||
})
|
})
|
||||||
region!: string;
|
region!: string;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput(
|
||||||
title: "负载均衡ID",
|
createRemoteSelectInputDefine({
|
||||||
required: true,
|
title: "负载均衡ID",
|
||||||
})
|
helper: "请选择要部署证书的负载均衡",
|
||||||
|
action: DeployCertToTencentCLB.prototype.onGetCLBList.name,
|
||||||
|
watches: ["region"],
|
||||||
|
single: true,
|
||||||
|
pager: false,
|
||||||
|
search: false,
|
||||||
|
})
|
||||||
|
)
|
||||||
loadBalancerId!: string;
|
loadBalancerId!: string;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput(
|
||||||
title: "监听器ID",
|
createRemoteSelectInputDefine({
|
||||||
required: true,
|
title: "监听器ID",
|
||||||
})
|
helper: "请选择要部署证书的HTTPS监听器",
|
||||||
|
action: DeployCertToTencentCLB.prototype.onGetListenerList.name,
|
||||||
|
watches: ["region", "loadBalancerId"],
|
||||||
|
single: true,
|
||||||
|
pager: false,
|
||||||
|
search: false,
|
||||||
|
})
|
||||||
|
)
|
||||||
listenerId!: string;
|
listenerId!: string;
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput(
|
||||||
title: "域名",
|
createRemoteSelectInputDefine({
|
||||||
required: false,
|
title: "域名",
|
||||||
component: {
|
helper: "如果开启了SNI,请选择要部署证书的域名;未开启SNI时可以留空",
|
||||||
name: "a-select",
|
action: DeployCertToTencentCLB.prototype.onGetDomainList.name,
|
||||||
vModel: "value",
|
watches: ["region", "loadBalancerId", "listenerId"],
|
||||||
open: false,
|
required: false,
|
||||||
mode: "tags",
|
single: false,
|
||||||
},
|
pager: false,
|
||||||
helper: "如果开启了sni,则此项必须填写,未开启,则不要填写",
|
search: false,
|
||||||
})
|
})
|
||||||
|
)
|
||||||
domain!: string | string[];
|
domain!: string | string[];
|
||||||
|
|
||||||
@TaskInput({
|
@TaskInput({
|
||||||
@@ -272,6 +288,27 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
|
|||||||
return ret.LoadBalancerSet;
|
return ret.LoadBalancerSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onGetCLBList(data: PageSearch) {
|
||||||
|
if (!this.accessId) {
|
||||||
|
throw new Error("请选择Access提供者");
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = await this.getClient();
|
||||||
|
const list = await this.getCLBList(client);
|
||||||
|
if (!list || list.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.map((item: any) => {
|
||||||
|
const loadBalancerId = item.LoadBalancerId;
|
||||||
|
const loadBalancerName = item.LoadBalancerName || loadBalancerId;
|
||||||
|
return {
|
||||||
|
value: loadBalancerId,
|
||||||
|
label: `${loadBalancerName}<${loadBalancerId}>`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getListenerList(client: any, balancerId: any, listenerIds: any) {
|
async getListenerList(client: any, balancerId: any, listenerIds: any) {
|
||||||
// HTTPS
|
// HTTPS
|
||||||
const params = {
|
const params = {
|
||||||
@@ -284,6 +321,57 @@ export class DeployCertToTencentCLB extends AbstractTaskPlugin {
|
|||||||
return ret.Listeners;
|
return ret.Listeners;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onGetListenerList(data: PageSearch) {
|
||||||
|
if (!this.accessId) {
|
||||||
|
throw new Error("请选择Access提供者");
|
||||||
|
}
|
||||||
|
if (!this.loadBalancerId) {
|
||||||
|
throw new Error("请先选择负载均衡");
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = await this.getClient();
|
||||||
|
const list = await this.getListenerList(client, this.loadBalancerId, null);
|
||||||
|
if (!list || list.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.map((item: any) => {
|
||||||
|
const listenerId = item.ListenerId;
|
||||||
|
const listenerName = item.ListenerName || "HTTPS监听器";
|
||||||
|
const port = item.Port ? `:${item.Port}` : "";
|
||||||
|
return {
|
||||||
|
value: listenerId,
|
||||||
|
label: `${listenerName}${port}<${listenerId}>`,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async onGetDomainList(data: PageSearch) {
|
||||||
|
if (!this.accessId) {
|
||||||
|
throw new Error("请选择Access提供者");
|
||||||
|
}
|
||||||
|
if (!this.loadBalancerId) {
|
||||||
|
throw new Error("请先选择负载均衡");
|
||||||
|
}
|
||||||
|
if (!this.listenerId) {
|
||||||
|
throw new Error("请先选择监听器");
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = await this.getClient();
|
||||||
|
const listeners = await this.getListenerList(client, this.loadBalancerId, [this.listenerId]);
|
||||||
|
const listener = listeners?.[0];
|
||||||
|
const domains = listener?.Rules?.map((rule: any) => rule.Domain).filter(Boolean) || [];
|
||||||
|
const uniqueDomains = [...new Set(domains)];
|
||||||
|
|
||||||
|
return uniqueDomains.map(domain => {
|
||||||
|
return {
|
||||||
|
value: domain,
|
||||||
|
label: domain,
|
||||||
|
domain,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
checkRet(ret: any) {
|
checkRet(ret: any) {
|
||||||
if (!ret || ret.Error) {
|
if (!ret || ret.Error) {
|
||||||
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
|
throw new Error("执行失败:" + ret.Error.Code + "," + ret.Error.Message);
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
23:35
|
01:14
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
23:54
|
01:28
|
||||||
|
|||||||
Reference in New Issue
Block a user