diff --git a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
index 4c949b63a..018da9e1d 100644
--- a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
+++ b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts
@@ -282,6 +282,9 @@ export default {
disabled: "Enable/Disable",
ipCheck: "Enable IP Check",
ipSyncAuto: "Enable IP Sync Auto",
+ ipSyncMode: "IP Sync Mode",
+ ipIgnoreCoherence: "Ignore Certificate Coherence",
+ ipIgnoreCoherenceHelper: "Enable to ignore certificate coherence check, only check certificate expiration time",
selectRequired: "Please select",
ipCheckConfirm: "Are you sure to {status} IP check?",
ipCount: "IP Count",
diff --git a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
index 02e874e5b..17030ec5b 100644
--- a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
+++ b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts
@@ -286,9 +286,16 @@ export default {
disabled: "禁用启用",
ipCheck: "开启IP检查",
ipSyncAuto: "自动同步IP",
+ ipSyncMode: "IP同步模式",
+ ipSyncModeHelper: "选择仅检查IPv4或IPv6,或检查所有IP",
+ ipSyncModeAll: "检查所有IP",
+ ipSyncModeIPV4Only: "仅检查IPv4",
+ ipSyncModeIPV6Only: "仅检查IPv6",
selectRequired: "请选择",
ipCheckConfirm: "确定{status}IP检查?",
ipCount: "IP数量",
+ ipIgnoreCoherence: "忽略证书一致性",
+ ipIgnoreCoherenceHelper: "开启后,即使IP上的证书与站点证书不一致,也会被认为是正常,仅校验证书过期时间",
checkStatus: "检查状态",
pipelineId: "关联流水线ID",
certInfoId: "证书ID",
diff --git a/packages/ui/certd-client/src/views/certd/addon/addon-selector/index.vue b/packages/ui/certd-client/src/views/certd/addon/addon-selector/index.vue
index 61776a66f..e7e75e6eb 100644
--- a/packages/ui/certd-client/src/views/certd/addon/addon-selector/index.vue
+++ b/packages/ui/certd-client/src/views/certd/addon/addon-selector/index.vue
@@ -148,7 +148,6 @@ async function refreshTarget(value: any) {
type: "",
};
}
- debugger
}
watch(
diff --git a/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx b/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx
index f48fca630..713c6b5ec 100644
--- a/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx
+++ b/packages/ui/certd-client/src/views/certd/monitor/site/crud.tsx
@@ -610,6 +610,46 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
},
},
},
+ checkStatus: {
+ title: t("certd.monitor.checkStatus"),
+ search: {
+ show: false,
+ },
+ type: "dict-select",
+ dict: checkStatusDict,
+ form: {
+ show: false,
+ },
+ column: {
+ width: 100,
+ align: "center",
+ sorter: true,
+ cellRender({ value, row }) {
+ return (
+
+
+
+ );
+ },
+ },
+ },
+ // error: {
+ // title: "错误信息",
+ // search: {
+ // show: false
+ // },
+ // type: "text",
+ // form: {
+ // show: false
+ // },
+ // column: {
+ // width: 200,
+ // sorter: true,
+ // cellRender({ value }) {
+ // return {value};
+ // }
+ // }
+ // },
ipCheck: {
title: t("certd.monitor.ipCheck"),
type: "dict-switch",
@@ -672,46 +712,51 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
align: "center",
},
},
- checkStatus: {
- title: t("certd.monitor.checkStatus"),
- search: {
- show: false,
- },
+ ipSyncMode: {
+ title: t("certd.monitor.ipSyncMode"),
type: "dict-select",
- dict: checkStatusDict,
+ dict: dict({
+ data: [
+ { label: t("certd.monitor.ipSyncModeAll"), value: "all" },
+ { label: t("certd.monitor.ipSyncModeIPV4Only"), value: "ipv4" },
+ { label: t("certd.monitor.ipSyncModeIPV6Only"), value: "ipv6" },
+ ],
+ }),
form: {
- show: false,
+ value: "all",
+ show: compute(({ form }) => {
+ return form.ipSyncAuto;
+ }),
+ helper: t("certd.monitor.ipSyncModeHelper"),
},
column: {
width: 100,
- align: "center",
sorter: true,
- cellRender({ value, row }) {
- return (
-
-
-
- );
- },
+ align: "center",
+ },
+ },
+ ipIgnoreCoherence: {
+ title: t("certd.monitor.ipIgnoreCoherence"),
+ type: "dict-switch",
+ dict: dict({
+ data: [
+ { label: t("common.enabled"), value: true, color: "green" },
+ { label: t("common.disabled"), value: false, color: "gray" },
+ ],
+ }),
+ form: {
+ value: false,
+ show: compute(({ form }) => {
+ return form.ipCheck;
+ }),
+ helper: t("certd.monitor.ipIgnoreCoherenceHelper"),
+ },
+ column: {
+ width: 100,
+ sorter: true,
+ align: "center",
},
},
- // error: {
- // title: "错误信息",
- // search: {
- // show: false
- // },
- // type: "text",
- // form: {
- // show: false
- // },
- // column: {
- // width: 200,
- // sorter: true,
- // cellRender({ value }) {
- // return {value};
- // }
- // }
- // },
pipelineId: {
title: t("certd.monitor.pipelineId"),
search: {
diff --git a/packages/ui/certd-server/db/migration/v10036__ipcheck.sql b/packages/ui/certd-server/db/migration/v10036__ipcheck.sql
index 49ed5882a..8553f3251 100644
--- a/packages/ui/certd-server/db/migration/v10036__ipcheck.sql
+++ b/packages/ui/certd-server/db/migration/v10036__ipcheck.sql
@@ -1,4 +1,6 @@
-ALTER TABLE cd_site_info ADD COLUMN ip_sync_auto boolean DEFAULT (1);
+ALTER TABLE cd_site_info ADD COLUMN ip_sync_auto boolean;
+ALTER TABLE cd_site_info ADD COLUMN ip_sync_mode varchar(20);
+ALTER TABLE cd_site_info ADD COLUMN ip_ignore_coherence boolean;
ALTER TABLE pi_pipeline ADD COLUMN webhook_key varchar(100);
ALTER TABLE pi_pipeline ADD COLUMN trigger_count integer DEFAULT (0);
diff --git a/packages/ui/certd-server/src/controller/user/monitor/site-info-controller.ts b/packages/ui/certd-server/src/controller/user/monitor/site-info-controller.ts
index 4431c5b8b..4ebda0274 100644
--- a/packages/ui/certd-server/src/controller/user/monitor/site-info-controller.ts
+++ b/packages/ui/certd-server/src/controller/user/monitor/site-info-controller.ts
@@ -5,6 +5,7 @@ import { SiteInfoService } from "../../../modules/monitor/service/site-info-serv
import { UserSiteMonitorSetting } from "../../../modules/mine/service/models.js";
import { merge } from "lodash-es";
import {SiteIpService} from "../../../modules/monitor/service/site-ip-service.js";
+import { utils } from "@certd/basic";
/**
*/
@@ -104,6 +105,7 @@ export class SiteInfoController extends CrudController {
async check(@Body('id') id: number) {
await this.service.checkUserId(id, this.getUserId());
await this.service.check(id, true, 0);
+ await utils.sleep(1000);
return this.ok();
}
diff --git a/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts b/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts
index 36591f6a5..298ffe193 100644
--- a/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts
+++ b/packages/ui/certd-server/src/modules/monitor/entity/site-info.ts
@@ -49,6 +49,12 @@ export class SiteInfoEntity {
@Column({ name: 'ip_sync_auto', comment: '是否自动同步IP' })
ipSyncAuto: boolean;
+ @Column({ name: 'ip_sync_mode', comment: 'IP同步模式' })
+ ipSyncMode: string;
+
+ @Column({ name: 'ip_ignore_coherence', comment: '忽略证书一致性' })
+ ipIgnoreCoherence: boolean;
+
@Column({ name: 'ip_count', comment: 'ip数量' })
ipCount: number
diff --git a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts
index 5aae1cf71..42f886a28 100644
--- a/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts
+++ b/packages/ui/certd-server/src/modules/monitor/service/site-info-service.ts
@@ -162,16 +162,16 @@ export class SiteInfoService extends BaseService {
}
await this.update(updateData);
-
+ const setting = await this.userSettingsService.getSetting(site.userId, UserSiteMonitorSetting)
//检查ip
- await this.checkAllIp(site,retryTimes);
+ await this.checkAllIp(site,retryTimes,setting);
if (!notify) {
return;
}
try {
- await this.sendExpiresNotify(site.id);
+ await this.sendExpiresNotify(site.id,setting);
} catch (e) {
logger.error("send notify error", e);
}
@@ -187,18 +187,19 @@ export class SiteInfoService extends BaseService {
return;
}
try {
- await this.sendCheckErrorNotify(site.id);
+ await this.sendCheckErrorNotify(site.id,false,setting);
} catch (e) {
logger.error("send notify error", e);
}
}
}
- async checkAllIp(site: SiteInfoEntity,retryTimes = null) {
+ async checkAllIp(site: SiteInfoEntity,retryTimes = null,setting: UserSiteMonitorSetting) {
if (!site.ipCheck) {
return;
}
const certExpiresTime = site.certExpiresTime;
+ const tipDays = setting?.certValidDays || 10;
const onFinished = async (list: SiteIpEntity[]) => {
let errorCount = 0;
let errorMessage = "";
@@ -207,11 +208,19 @@ export class SiteInfoService extends BaseService {
continue;
}
errorCount++;
+
+ const isExpired = dayjs().valueOf() > dayjs(item.certExpiresTime).valueOf();
+ const isWillExpired = dayjs().valueOf() > dayjs(item.certExpiresTime).subtract(tipDays, "day").valueOf();
+
if (item.error) {
errorMessage += `${item.ipAddress}:${item.error}; \n`;
- } else if (item.certExpiresTime !== certExpiresTime) {
+ } else if (item.certExpiresTime !== certExpiresTime && !site.ipIgnoreCoherence) {
errorMessage += `${item.ipAddress}:与主站证书过期时间不一致(主站:${dayjs(certExpiresTime).format("YYYY-MM-DD")},IP:${dayjs(item.certExpiresTime).format("YYYY-MM-DD")}); \n`;
- } else {
+ } else if (isExpired){
+ errorMessage += `${item.ipAddress}:证书已过期(过期时间:${dayjs(item.certExpiresTime).format("YYYY-MM-DD")}); \n`;
+ }else if (isWillExpired){
+ errorMessage += `${item.ipAddress}:证书将过期(过期时间:${dayjs(item.certExpiresTime).format("YYYY-MM-DD")}); \n`;
+ }else {
errorCount--;
}
}
@@ -232,12 +241,12 @@ export class SiteInfoService extends BaseService {
ipErrorCount: errorCount
});
try {
- await this.sendCheckErrorNotify(site.id, true);
+ await this.sendCheckErrorNotify(site.id, true,setting);
} catch (e) {
logger.error("send notify error", e);
}
};
- if (!site.ipSyncAuto) {
+ if (site.ipSyncAuto === false) {
await this.siteIpService.checkAll(site, retryTimes,onFinished);
}else{
await this.siteIpService.syncAndCheck(site, retryTimes,onFinished);
@@ -246,7 +255,7 @@ export class SiteInfoService extends BaseService {
}
/**
- * 检查
+ * 检查,不等待返回
* @param id
* @param notify
* @param retryTimes
@@ -256,13 +265,16 @@ export class SiteInfoService extends BaseService {
if (!site) {
throw new Error("站点不存在");
}
- return await this.doCheck(site, notify, retryTimes);
+
+ this.doCheck(site, notify, retryTimes).catch((err) => {
+ logger.error("check site error", err);
+ });
+ return
}
- async sendCheckErrorNotify(siteId: number, fromIpCheck = false) {
+ async sendCheckErrorNotify(siteId: number, fromIpCheck = false,setting: UserSiteMonitorSetting) {
const site = await this.info(siteId);
const url = await this.notificationService.getBindUrl("#/certd/monitor/site");
- const setting = await this.userSettingsService.getSetting(site.userId, UserSiteMonitorSetting)
// 发邮件
await this.notificationService.send(
{
@@ -281,11 +293,9 @@ export class SiteInfoService extends BaseService {
);
}
- async sendExpiresNotify(siteId: number) {
- const site = await this.info(siteId);
- const setting = await this.userSettingsService.getSetting(site.userId, UserSiteMonitorSetting)
+ async sendExpiresNotify(siteId: number,setting: UserSiteMonitorSetting) {
const tipDays = setting?.certValidDays || 10;
-
+ const site = await this.info(siteId);
const expires = site.certExpiresTime;
const validDays = dayjs(expires).diff(dayjs(), "day");
const url = await this.notificationService.getBindUrl("#/certd/monitor/site");
diff --git a/packages/ui/certd-server/src/modules/monitor/service/site-ip-service.ts b/packages/ui/certd-server/src/modules/monitor/service/site-ip-service.ts
index eb005d539..6d4eb6157 100644
--- a/packages/ui/certd-server/src/modules/monitor/service/site-ip-service.ts
+++ b/packages/ui/certd-server/src/modules/monitor/service/site-ip-service.ts
@@ -76,7 +76,7 @@ export class SiteIpService extends BaseService {
}
//从域名解析中获取所有ip
- const ips = await this.getAllIpsFromDomain(domain,resolver);
+ const ips = await this.getAllIpsFromDomain(domain,resolver,entity.ipSyncMode);
if (ips.length === 0 ) {
logger.warn(`没有发现${domain}的IP`)
return
@@ -126,7 +126,7 @@ export class SiteIpService extends BaseService {
}
}
- async check(ipId: number, domain: string, port: number,retryTimes = null) {
+ async check(ipId: number, domain: string, port: number,retryTimes = null ,tipDays = 10) {
if(!ipId){
return
}
@@ -231,7 +231,7 @@ export class SiteIpService extends BaseService {
})
}
- async getAllIpsFromDomain(domain: string,resolver:any = dns):Promise {
+ async getAllIpsFromDomain(domain: string,resolver:any = dns,ipSyncMode:string = "all"):Promise {
const getFromV4 = async ():Promise => {
try{
return await resolver.resolve4(domain);
@@ -249,6 +249,12 @@ export class SiteIpService extends BaseService {
}
}
+ if (ipSyncMode === "ipv4") {
+ return await getFromV4();
+ }
+ if (ipSyncMode === "ipv6") {
+ return await getFromV6();
+ }
return Promise.all([getFromV4(), getFromV6()]).then(res => {
return [...res[0], ...res[1]];