2025-12-25 18:56:27 +08:00
|
|
|
|
// 导入所需的 SDK 模块
|
|
|
|
|
|
import { AwsAccess } from '../access.js';
|
|
|
|
|
|
import { CertInfo } from '@certd/plugin-cert';
|
2025-12-26 23:20:14 +08:00
|
|
|
|
import { ILogger, utils } from '@certd/basic';
|
|
|
|
|
|
type AwsClientOptions = { access: AwsAccess; region: string, logger: ILogger };
|
2025-12-25 18:56:27 +08:00
|
|
|
|
|
|
|
|
|
|
export class AwsClient {
|
|
|
|
|
|
options: AwsClientOptions;
|
|
|
|
|
|
access: AwsAccess;
|
|
|
|
|
|
region: string;
|
|
|
|
|
|
logger: ILogger;
|
|
|
|
|
|
constructor(options: AwsClientOptions) {
|
|
|
|
|
|
this.options = options;
|
|
|
|
|
|
this.access = options.access;
|
|
|
|
|
|
this.region = options.region;
|
|
|
|
|
|
this.logger = options.logger;
|
|
|
|
|
|
}
|
|
|
|
|
|
async importCertificate(certInfo: CertInfo) {
|
|
|
|
|
|
// 创建 ACM 客户端
|
|
|
|
|
|
const { ACMClient, ImportCertificateCommand } = await import('@aws-sdk/client-acm');
|
|
|
|
|
|
const acmClient = new ACMClient({
|
|
|
|
|
|
region: this.region, // 替换为您的 AWS 区域
|
|
|
|
|
|
credentials: {
|
|
|
|
|
|
accessKeyId: this.access.accessKeyId, // 从环境变量中读取
|
|
|
|
|
|
secretAccessKey: this.access.secretAccessKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const cert = certInfo.crt.split('-----END CERTIFICATE-----')[0] + '-----END CERTIFICATE-----';
|
|
|
|
|
|
// 构建上传参数
|
|
|
|
|
|
const data = await acmClient.send(
|
|
|
|
|
|
new ImportCertificateCommand({
|
|
|
|
|
|
Certificate: Buffer.from(cert),
|
|
|
|
|
|
PrivateKey: Buffer.from(certInfo.key),
|
|
|
|
|
|
// CertificateChain: certificateChain, // 可选
|
|
|
|
|
|
})
|
|
|
|
|
|
);
|
|
|
|
|
|
console.log('Upload successful:', data);
|
|
|
|
|
|
// 返回证书 ARN(Amazon Resource Name)
|
|
|
|
|
|
return data.CertificateArn;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
async route53ClientGet() {
|
|
|
|
|
|
const { Route53Client } = await import('@aws-sdk/client-route-53');
|
|
|
|
|
|
return new Route53Client({
|
|
|
|
|
|
region: this.region,
|
|
|
|
|
|
credentials: {
|
|
|
|
|
|
accessKeyId: this.access.accessKeyId, // 从环境变量中读取
|
|
|
|
|
|
secretAccessKey: this.access.secretAccessKey,
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-26 23:20:14 +08:00
|
|
|
|
async route53GetHostedZoneId(name: string): Promise<{ ZoneId: string, ZoneName: string }> {
|
2025-12-25 18:56:27 +08:00
|
|
|
|
const hostedZones = await this.route53ListHostedZones(name);
|
2025-12-26 23:20:14 +08:00
|
|
|
|
const zoneId = hostedZones[0].Id.replace('/hostedzone/', '');
|
2025-12-25 18:56:27 +08:00
|
|
|
|
this.logger.info(`获取到hostedZoneId:${zoneId},name:${hostedZones[0].Name}`);
|
|
|
|
|
|
return {
|
|
|
|
|
|
ZoneId: zoneId,
|
|
|
|
|
|
ZoneName: hostedZones[0].Name,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
2025-12-26 23:20:14 +08:00
|
|
|
|
async route53ListHostedZones(name: string): Promise<{ Id: string, Name: string }[]> {
|
|
|
|
|
|
const { ListHostedZonesByNameCommand } = await import("@aws-sdk/client-route-53"); // ES Modules import
|
2025-12-25 18:56:27 +08:00
|
|
|
|
|
|
|
|
|
|
const client = await this.route53ClientGet();
|
|
|
|
|
|
const input = { // ListHostedZonesByNameRequest
|
|
|
|
|
|
DNSName: name,
|
|
|
|
|
|
};
|
|
|
|
|
|
const command = new ListHostedZonesByNameCommand(input);
|
2025-12-26 23:20:14 +08:00
|
|
|
|
const response = await this.doRequest(() => client.send(command));
|
2025-12-25 18:56:27 +08:00
|
|
|
|
if (response.HostedZones.length === 0) {
|
|
|
|
|
|
throw new Error(`找不到 HostedZone ${name}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
this.logger.info(`获取到hostedZoneId:${JSON.stringify(response.HostedZones)}`);
|
|
|
|
|
|
return response.HostedZones;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-26 23:20:14 +08:00
|
|
|
|
async route53ChangeRecord(req: {
|
|
|
|
|
|
hostedZoneId: string, fullRecord: string, type: string, value: string, action: "UPSERT" | "DELETE"
|
|
|
|
|
|
}) {
|
|
|
|
|
|
const { ChangeResourceRecordSetsCommand } = await import("@aws-sdk/client-route-53"); // ES Modules import
|
2025-12-25 18:56:27 +08:00
|
|
|
|
// const { Route53Client, ChangeResourceRecordSetsCommand } = require("@aws-sdk/client-route-53"); // CommonJS import
|
|
|
|
|
|
// import type { Route53ClientConfig } from "@aws-sdk/client-route-53";
|
|
|
|
|
|
const client = await this.route53ClientGet();
|
|
|
|
|
|
const input = { // ChangeResourceRecordSetsRequest
|
|
|
|
|
|
HostedZoneId: req.hostedZoneId, // required
|
|
|
|
|
|
ChangeBatch: { // ChangeBatch
|
|
|
|
|
|
Changes: [ // Changes // required
|
|
|
|
|
|
{ // Change
|
2025-12-26 23:20:14 +08:00
|
|
|
|
Action: req.action as any, // required
|
2025-12-25 18:56:27 +08:00
|
|
|
|
ResourceRecordSet: { // ResourceRecordSet
|
2025-12-26 23:20:14 +08:00
|
|
|
|
Name: req.fullRecord, // required
|
2025-12-25 18:56:27 +08:00
|
|
|
|
Type: req.type.toUpperCase() as any,
|
|
|
|
|
|
ResourceRecords: [ // ResourceRecords
|
|
|
|
|
|
{ // ResourceRecord
|
|
|
|
|
|
Value: `"${req.value}"`, // required
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
2025-12-26 09:29:29 +08:00
|
|
|
|
TTL: 60,
|
2025-12-25 18:56:27 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
2025-12-26 23:20:14 +08:00
|
|
|
|
this.logger.info(`设置域名解析参数:${JSON.stringify(input)}`);
|
2025-12-25 18:56:27 +08:00
|
|
|
|
const command = new ChangeResourceRecordSetsCommand(input);
|
2025-12-26 23:20:14 +08:00
|
|
|
|
const response = await this.doRequest(() => client.send(command));
|
2025-12-25 18:56:27 +08:00
|
|
|
|
console.log('Add record successful:', JSON.stringify(response));
|
|
|
|
|
|
await utils.sleep(3000);
|
|
|
|
|
|
return response;
|
|
|
|
|
|
/*
|
|
|
|
|
|
// { // ChangeResourceRecordSetsResponse
|
|
|
|
|
|
// ChangeInfo: { // ChangeInfo
|
|
|
|
|
|
// Id: "STRING_VALUE", // required
|
|
|
|
|
|
// Status: "PENDING" || "INSYNC", // required
|
|
|
|
|
|
// SubmittedAt: new Date("TIMESTAMP"), // required
|
|
|
|
|
|
// Comment: "STRING_VALUE",
|
|
|
|
|
|
// },
|
|
|
|
|
|
// };*/
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-26 23:20:14 +08:00
|
|
|
|
async doRequest<T>(call: () => Promise<T>): Promise<T> {
|
|
|
|
|
|
try {
|
2025-12-25 18:56:27 +08:00
|
|
|
|
return await call();
|
2025-12-26 23:20:14 +08:00
|
|
|
|
} catch (err) {
|
2025-12-25 18:56:27 +08:00
|
|
|
|
this.logger.error(`调用接口失败:${err.Error?.Message || err.message},requestId:${err.requestId}`);
|
|
|
|
|
|
throw err;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|