Files
certd/packages/ui/certd-server/src/plugins/plugin-fnos/index.ts

181 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { AbstractTaskPlugin, IsTaskPlugin, pluginGroups, RunStrategy, TaskInput } from "@certd/pipeline";
import { CertApplyPluginNames, CertInfo, CertReader } from "@certd/plugin-cert";
import {
createCertDomainGetterInputDefine,
createRemoteSelectInputDefine,
SshAccess,
SshClient
} from "@certd/plugin-lib";
import path from "node:path";
@IsTaskPlugin({
//命名规范,插件类型+功能就是目录plugin-demo中的demo大写字母开头驼峰命名
name: "FnOSDeployToNAS",
title: "飞牛NAS-部署证书",
icon: "svg:icon-lucky",
//插件分组
group: pluginGroups.panel.key,
needPlus: false,
default: {
//默认值配置照抄即可
strategy: {
runStrategy: RunStrategy.SkipWhenSucceed
}
}
})
//类名规范跟上面插件名称name一致
export class FnOSDeployToNAS extends AbstractTaskPlugin {
//证书选择,此项必须要有
@TaskInput({
title: "域名证书",
helper: "请选择前置任务输出的域名证书",
component: {
name: "output-selector",
from: [...CertApplyPluginNames]
}
// required: true, // 必填
})
cert!: CertInfo;
@TaskInput(createCertDomainGetterInputDefine({ props: { required: false } }))
certDomains!: string[];
//授权选择框
@TaskInput({
title: "飞牛SSH授权",
component: {
name: "access-selector",
type: "ssh" //固定授权类型
},
helper:"请先配置sudo免密\nsudo visudo\n#在文件最后一行增加以下内容需要将username替换成自己的用户名\nusername ALL=(ALL) NOPASSWD: NOPASSWD: ALL\nctrl+x 保存退出",
required: true //必填
})
accessId!: string;
@TaskInput(
createRemoteSelectInputDefine({
title: "证书Id",
helper: "要更新的证书id",
action: FnOSDeployToNAS.prototype.onGetCertList.name
})
)
certList!: number[];
//插件实例化时执行的方法
async onInstance() {
}
//插件执行方法
async execute(): Promise<void> {
const access: SshAccess = await this.getAccess<SshAccess>(this.accessId);
const client = new SshClient(this.logger);
//复制证书
const list = await this.doGetCertList()
const certReader = new CertReader(this.cert);
const expiresAt = certReader.expires;
const validFrom = certReader.detail.notBefore.getTime()
for (const target of this.certList) {
this.logger.info(`----------- 准备部署:${target}`);
let found = false
for (const item of list) {
if (item.sum === target) {
this.logger.info(`----------- 找到证书,开始部署:${item.sum},${item.domain}`)
const certPath = item.certificate;
const keyPath = item.privateKey;
const certDir = path.dirname(keyPath)
const cmd = `
sudo tee ${certPath} > /dev/null <<'EOF'
${this.cert.crt}
EOF
sudo tee ${keyPath} > /dev/null <<'EOF'
${this.cert.key}
EOF
sudo chmod 0755 "${certDir}/" -R
sudo -u postgres psql -d trim_connect -c "UPDATE cert SET valid_to=${expiresAt},valid_from=${validFrom} WHERE private_key='${item.privateKey}'"
`
const res = await client.exec({
connectConf: access,
script: cmd
});
if (res.indexOf("Permission denied") > -1){
this.logger.error("权限不足,请先配置 sudo 免密")
}
found = true
break
}
}
if (!found) {
throw new Error(`没有找到证书:${target}请修改任务重新选择证书id`);
}
}
this.logger.info("证书已上传,准备重启...");
const restartCmd= `
echo "正在重启相关服务..."
sudo systemctl restart webdav.service
sudo systemctl restart smbftpd.service
sudo systemctl restart trim_nginx.service
echo "服务重启完成!"
`
await client.exec({
connectConf: access,
script: restartCmd
});
this.logger.info("部署完成");
}
async doGetCertList(){
const access: SshAccess = await this.getAccess<SshAccess>(this.accessId);
const client = new SshClient(this.logger);
/**
* :/usr/trim/etc$ cat network_cert_all.conf | jq .
*/
const sslListCmd = "cat /usr/trim/etc/network_cert_all.conf | jq ."
const res:string = await client.exec({
connectConf: access,
script: sslListCmd
});
let list = []
try{
list = JSON.parse(res.trim())
}catch (e){
throw new Error(`证书列表解析失败:${res}`)
}
if (!list || list.length === 0) {
throw new Error("没有找到证书,请先在证书管理也没上传一次证书");
}
return list
}
async onGetCertList() {
const list = await this.doGetCertList()
const options = list.map((item: any) => {
return {
label: `${item.domain}<${item.used?'已使用':"未使用"}-${item.sum}>`,
value: item.sum,
domain: item.san
};
});
return this.ctx.utils.options.buildGroupOptions(options, this.certDomains);
}
}
new FnOSDeployToNAS();