mirror of
https://github.com/certd/certd.git
synced 2026-04-14 12:30:54 +08:00
Compare commits
5 Commits
v1.36.11
...
v2-dev-ord
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
69e6f2362e | ||
|
|
ab84835362 | ||
|
|
41ce8489dc | ||
|
|
edf089ec9e | ||
|
|
0ae9a3605c |
@@ -1 +1 @@
|
|||||||
2
|
12:27
|
||||||
|
|||||||
@@ -3,6 +3,12 @@
|
|||||||
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.36.11](https://github.com/certd/certd/compare/v1.36.10...v1.36.11) (2025-07-22)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 安全更新,备份数据库插件仅限管理员运行 ([13dfca1](https://github.com/certd/certd/commit/13dfca1749275526c82465a17c482b607c820fdd))
|
||||||
|
|
||||||
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
## [1.36.10](https://github.com/certd/certd/compare/v1.36.9...v1.36.10) (2025-07-18)
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|||||||
@@ -69,5 +69,5 @@
|
|||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/publishlab/node-acme-client/issues"
|
"url": "https://github.com/publishlab/node-acme-client/issues"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,5 +45,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,5 +44,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,5 @@
|
|||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"tslib": "^2.8.1"
|
"tslib": "^2.8.1"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,5 +31,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,5 +61,5 @@
|
|||||||
"fetch"
|
"fetch"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,5 +32,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export * from './lib/k8s.client.js';
|
export * from "./lib/k8s.client.js";
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret } from '@kubernetes/client-node';
|
import { CoreV1Api, KubeConfig, NetworkingV1Api, V1Ingress, V1Secret } from "@kubernetes/client-node";
|
||||||
import dns from 'dns';
|
import dns from "dns";
|
||||||
import { ILogger } from '@certd/basic';
|
import { ILogger } from "@certd/basic";
|
||||||
import _ from 'lodash-es';
|
import _ from "lodash-es";
|
||||||
|
|
||||||
export type K8sClientOpts = {
|
export type K8sClientOpts = {
|
||||||
kubeConfigStr: string;
|
kubeConfigStr: string;
|
||||||
@@ -9,6 +9,7 @@ export type K8sClientOpts = {
|
|||||||
//{ [domain]:{ip:'xxx.xx.xxx'} }
|
//{ [domain]:{ip:'xxx.xx.xxx'} }
|
||||||
//暂时没用
|
//暂时没用
|
||||||
lookup?: any;
|
lookup?: any;
|
||||||
|
skipTLSVerify?: boolean;
|
||||||
};
|
};
|
||||||
export class K8sClient {
|
export class K8sClient {
|
||||||
kubeconfig!: KubeConfig;
|
kubeconfig!: KubeConfig;
|
||||||
@@ -16,10 +17,12 @@ export class K8sClient {
|
|||||||
lookup!: (hostnameReq: any, options: any, callback: any) => void;
|
lookup!: (hostnameReq: any, options: any, callback: any) => void;
|
||||||
client!: CoreV1Api;
|
client!: CoreV1Api;
|
||||||
logger: ILogger;
|
logger: ILogger;
|
||||||
|
skipTLSVerify?: boolean;
|
||||||
constructor(opts: K8sClientOpts) {
|
constructor(opts: K8sClientOpts) {
|
||||||
this.kubeConfigStr = opts.kubeConfigStr;
|
this.kubeConfigStr = opts.kubeConfigStr;
|
||||||
this.logger = opts.logger;
|
this.logger = opts.logger;
|
||||||
this.setLookup(opts.lookup);
|
this.setLookup(opts.lookup);
|
||||||
|
this.skipTLSVerify = opts.skipTLSVerify;
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,6 +30,18 @@ export class K8sClient {
|
|||||||
const kubeconfig = new KubeConfig();
|
const kubeconfig = new KubeConfig();
|
||||||
kubeconfig.loadFromString(this.kubeConfigStr);
|
kubeconfig.loadFromString(this.kubeConfigStr);
|
||||||
this.kubeconfig = kubeconfig;
|
this.kubeconfig = kubeconfig;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (this.skipTLSVerify == true) {
|
||||||
|
for (const cluster of kubeconfig.getClusters()) {
|
||||||
|
// @ts-ignore
|
||||||
|
cluster["skipTLSVerify"] = this.skipTLSVerify;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.warn("skipTLSVerify error", e);
|
||||||
|
}
|
||||||
|
|
||||||
this.client = kubeconfig.makeApiClient(CoreV1Api);
|
this.client = kubeconfig.makeApiClient(CoreV1Api);
|
||||||
|
|
||||||
// const reqOpts = { kubeconfig, request: {} } as any;
|
// const reqOpts = { kubeconfig, request: {} } as any;
|
||||||
@@ -47,9 +62,9 @@ export class K8sClient {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.lookup = (hostnameReq: any, options: any, callback: any) => {
|
this.lookup = (hostnameReq: any, options: any, callback: any) => {
|
||||||
this.logger.info('custom lookup', hostnameReq, localRecords);
|
this.logger.info("custom lookup", hostnameReq, localRecords);
|
||||||
if (localRecords[hostnameReq]) {
|
if (localRecords[hostnameReq]) {
|
||||||
this.logger.info('local record', hostnameReq, localRecords[hostnameReq]);
|
this.logger.info("local record", hostnameReq, localRecords[hostnameReq]);
|
||||||
callback(null, localRecords[hostnameReq].ip, 4);
|
callback(null, localRecords[hostnameReq].ip, 4);
|
||||||
} else {
|
} else {
|
||||||
dns.lookup(hostnameReq, options, callback);
|
dns.lookup(hostnameReq, options, callback);
|
||||||
@@ -63,7 +78,7 @@ export class K8sClient {
|
|||||||
* @returns secretsList
|
* @returns secretsList
|
||||||
*/
|
*/
|
||||||
async getSecrets(opts: { namespace: string }) {
|
async getSecrets(opts: { namespace: string }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
return await this.client.listNamespacedSecret(namespace);
|
return await this.client.listNamespacedSecret(namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,9 +88,9 @@ export class K8sClient {
|
|||||||
* @returns {Promise<*>}
|
* @returns {Promise<*>}
|
||||||
*/
|
*/
|
||||||
async createSecret(opts: { namespace: string; body: V1Secret }) {
|
async createSecret(opts: { namespace: string; body: V1Secret }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const created = await this.client.createNamespacedSecret(namespace, opts.body);
|
const created = await this.client.createNamespacedSecret(namespace, opts.body);
|
||||||
this.logger.info('new secrets:', opts.body);
|
this.logger.info("new secrets:", opts.body);
|
||||||
return created.body;
|
return created.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,24 +104,24 @@ export class K8sClient {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
async patchSecret(opts: { namespace: string; secretName: string; body: V1Secret }) {
|
async patchSecret(opts: { namespace: string; secretName: string; body: V1Secret }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const secretName = opts.secretName;
|
const secretName = opts.secretName;
|
||||||
if (secretName == null) {
|
if (secretName == null) {
|
||||||
throw new Error('secretName 不能为空');
|
throw new Error("secretName 不能为空");
|
||||||
}
|
}
|
||||||
this.logger.info('patch secret:', secretName, namespace);
|
this.logger.info("patch secret:", secretName, namespace);
|
||||||
const oldSecret = await this.client.readNamespacedSecret(secretName, namespace);
|
const oldSecret = await this.client.readNamespacedSecret(secretName, namespace);
|
||||||
const newSecret = _.merge(oldSecret.body, opts.body);
|
const newSecret = _.merge(oldSecret.body, opts.body);
|
||||||
const res = await this.client.replaceNamespacedSecret(secretName, namespace, newSecret);
|
const res = await this.client.replaceNamespacedSecret(secretName, namespace, newSecret);
|
||||||
this.logger.info('secret updated');
|
this.logger.info("secret updated");
|
||||||
return res.body;
|
return res.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getIngressList(opts: { namespace: string }) {
|
async getIngressList(opts: { namespace: string }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
||||||
const res = await client.listNamespacedIngress(namespace);
|
const res = await client.listNamespacedIngress(namespace);
|
||||||
this.logger.info('ingress list get:', res.body);
|
this.logger.info("ingress list get:", res.body);
|
||||||
return res.body;
|
return res.body;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,17 +137,17 @@ export class K8sClient {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
async patchIngress(opts: { namespace: string; ingressName: string; body: V1Ingress }) {
|
async patchIngress(opts: { namespace: string; ingressName: string; body: V1Ingress }) {
|
||||||
const namespace = opts.namespace || 'default';
|
const namespace = opts.namespace || "default";
|
||||||
const ingressName = opts.ingressName;
|
const ingressName = opts.ingressName;
|
||||||
if (!ingressName) {
|
if (!ingressName) {
|
||||||
throw new Error('ingressName 不能为空');
|
throw new Error("ingressName 不能为空");
|
||||||
}
|
}
|
||||||
this.logger.info('patch ingress:', ingressName, namespace);
|
this.logger.info("patch ingress:", ingressName, namespace);
|
||||||
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
const client = this.kubeconfig.makeApiClient(NetworkingV1Api);
|
||||||
const oldIngress = await client.readNamespacedIngress(ingressName, namespace);
|
const oldIngress = await client.readNamespacedIngress(ingressName, namespace);
|
||||||
const newIngress = _.merge(oldIngress.body, opts.body);
|
const newIngress = _.merge(oldIngress.body, opts.body);
|
||||||
const res = await client.replaceNamespacedIngress(ingressName, namespace, newIngress);
|
const res = await client.replaceNamespacedIngress(ingressName, namespace, newIngress);
|
||||||
this.logger.info('ingress patched', opts.body);
|
this.logger.info("ingress patched", opts.body);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,5 +61,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,5 +46,5 @@
|
|||||||
"typeorm": "^0.3.11",
|
"typeorm": "^0.3.11",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,5 +43,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,5 +53,5 @@
|
|||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"typescript": "^5.4.2"
|
"typescript": "^5.4.2"
|
||||||
},
|
},
|
||||||
"gitHead": "085bdf5cfa9140903611aa12cdd2542d05aba321"
|
"gitHead": "7f9c4e52ac5c3837b251d3b2508457ce802e11cb"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,6 +280,10 @@ function openUpgrade() {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const productListUrl = computed(() => {
|
||||||
|
return `http://localhost:1017/subject/#/product/list?appKey=${settingStore.installInfo.appKey}&subjectId=${settingStore.installInfo.siteId}`;
|
||||||
|
});
|
||||||
|
|
||||||
const modalRef = modal.confirm({
|
const modalRef = modal.confirm({
|
||||||
title,
|
title,
|
||||||
async onOk() {
|
async onOk() {
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ export default {
|
|||||||
runCount: "Run Count",
|
runCount: "Run Count",
|
||||||
expiringCerts: "Soon-to-Expire Certificates",
|
expiringCerts: "Soon-to-Expire Certificates",
|
||||||
supportedTasks: "Overview of Supported Deployment Tasks",
|
supportedTasks: "Overview of Supported Deployment Tasks",
|
||||||
|
changeLog: "Change Log",
|
||||||
},
|
},
|
||||||
steps: {
|
steps: {
|
||||||
createPipeline: "Create Certificate Pipeline",
|
createPipeline: "Create Certificate Pipeline",
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ export default {
|
|||||||
runCount: "运行次数",
|
runCount: "运行次数",
|
||||||
expiringCerts: "最快到期证书",
|
expiringCerts: "最快到期证书",
|
||||||
supportedTasks: "已支持的部署任务总览",
|
supportedTasks: "已支持的部署任务总览",
|
||||||
|
changeLog: "更新日志",
|
||||||
},
|
},
|
||||||
steps: {
|
steps: {
|
||||||
createPipeline: "创建证书流水线",
|
createPipeline: "创建证书流水线",
|
||||||
|
|||||||
@@ -29,6 +29,10 @@
|
|||||||
</a-tag>
|
</a-tag>
|
||||||
</a-badge>
|
</a-badge>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
|
<a-tag color="blue" class="flex-inline pointer mr-0" @click="openChangeLogUrl()">
|
||||||
|
{{ t("certd.dashboard.changeLog") }}
|
||||||
|
</a-tag>
|
||||||
|
<a-divider type="vertical" />
|
||||||
<vip-button mode="nav" style="font-size: 12px"></vip-button>
|
<vip-button mode="nav" style="font-size: 12px"></vip-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="settingsStore.isComm">
|
<template v-if="settingsStore.isComm">
|
||||||
@@ -255,6 +259,9 @@ onMounted(async () => {
|
|||||||
function openUpgradeUrl() {
|
function openUpgradeUrl() {
|
||||||
window.open("https://certd.docmirror.cn/guide/install/upgrade.html");
|
window.open("https://certd.docmirror.cn/guide/install/upgrade.html");
|
||||||
}
|
}
|
||||||
|
function openChangeLogUrl() {
|
||||||
|
window.open("https://certd.docmirror.cn/guide/changelogs/CHANGELOG.html");
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
|||||||
@@ -136,6 +136,18 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
|
|||||||
ingressName!: string | string[];
|
ingressName!: string | string[];
|
||||||
|
|
||||||
|
|
||||||
|
@TaskInput({
|
||||||
|
title: "忽略证书校验",
|
||||||
|
required: false,
|
||||||
|
helper: "是否忽略证书校验",
|
||||||
|
component: {
|
||||||
|
name: "a-switch",
|
||||||
|
vModel: "checked",
|
||||||
|
}
|
||||||
|
})
|
||||||
|
skipTLSVerify!:boolean
|
||||||
|
|
||||||
|
|
||||||
// @TaskInput({ title: "集群内网ip", helper: "如果开启了外网的话,无需设置" })
|
// @TaskInput({ title: "集群内网ip", helper: "如果开启了外网的话,无需设置" })
|
||||||
// clusterIp!: string;
|
// clusterIp!: string;
|
||||||
|
|
||||||
@@ -163,7 +175,8 @@ export class DeployCertToTencentTKEIngressPlugin extends AbstractTaskPlugin {
|
|||||||
this.logger.info("kubeconfig已成功获取");
|
this.logger.info("kubeconfig已成功获取");
|
||||||
const k8sClient = new this.K8sClient({
|
const k8sClient = new this.K8sClient({
|
||||||
kubeConfigStr,
|
kubeConfigStr,
|
||||||
logger: this.logger
|
logger: this.logger,
|
||||||
|
skipTLSVerify: this.skipTLSVerify,
|
||||||
});
|
});
|
||||||
// if (this.clusterIp != null) {
|
// if (this.clusterIp != null) {
|
||||||
// if (!this.clusterDomain) {
|
// if (!this.clusterDomain) {
|
||||||
|
|||||||
Reference in New Issue
Block a user