Commit 986e6e82 authored by nanahira's avatar nanahira

rewrite

parent 2a14faa6
Pipeline #327 passed with stages
in 5 minutes and 57 seconds
...@@ -53,18 +53,31 @@ interface DomainRecordInfo { ...@@ -53,18 +53,31 @@ interface DomainRecordInfo {
} }
let config: Config; let config: Config;
let client: Aliyun;
let cdnRecordsRegex: RegExp[];
const requestOption = { const requestOption = {
method: "POST" method: "POST"
} }
async function getRecords(): Promise<DomainRecordInfo[]> { class Checker {
config: Config;
client: Aliyun;
cdnRecordsRegex: RegExp[];
static order: number = 0;
id: number;
constructor(config: Config) {
this.config = config;
this.client = new Aliyun(config.aliyun);
this.cdnRecordsRegex = config.cdnRecords.map(m => new RegExp(m.match));
this.id = ++Checker.order;
}
private message(msg: string) {
console.log(`${this.id} => ${msg}`);
}
async getRecords(): Promise<DomainRecordInfo[]> {
console.log(`Fetching domain records of ${config.domain}.`) console.log(`Fetching domain records of ${config.domain}.`)
const res: DomainRecordInfo[] = []; const res: DomainRecordInfo[] = [];
for (let i = 1; ; ++i) { for (let i = 1; ; ++i) {
const ret: DomainRecordReturnResult = await client.request("DescribeDomainRecords", { const ret: DomainRecordReturnResult = await this.client.request("DescribeDomainRecords", {
DomainName: config.domain, DomainName: config.domain,
PageNumber: i, PageNumber: i,
PageSize: 500, PageSize: 500,
...@@ -74,7 +87,7 @@ async function getRecords(): Promise<DomainRecordInfo[]> { ...@@ -74,7 +87,7 @@ async function getRecords(): Promise<DomainRecordInfo[]> {
break; break;
} }
for (let record of ret.DomainRecords.Record.filter(m => { for (let record of ret.DomainRecords.Record.filter(m => {
return m.RR && m.Type === "CNAME" && _.any(cdnRecordsRegex, r => !!m.RR.match(r)) && _.every(cdnRecordsRegex, r => { return m.RR && m.Type === "CNAME" && _.any(this.cdnRecordsRegex, r => !!m.RR.match(r)) && _.every(this.cdnRecordsRegex, r => {
if (!m.Value.endsWith(config.domain)) { if (!m.Value.endsWith(config.domain)) {
return true; return true;
} }
...@@ -88,57 +101,60 @@ async function getRecords(): Promise<DomainRecordInfo[]> { ...@@ -88,57 +101,60 @@ async function getRecords(): Promise<DomainRecordInfo[]> {
} }
} }
return res; return res;
} }
async checkNode(address: string, port: number): Promise<boolean> {
async function checkNode(address: string, port: number): Promise<boolean> {
let currentTestDomain: string; let currentTestDomain: string;
for (let i = 1; i <= config.retryCount; ++i) { for (let i = 1; i <= this.config.retryCount; ++i) {
try { try {
for (let testDomain of config.testDomains) { for (let testDomain of this.config.testDomains) {
currentTestDomain = testDomain; currentTestDomain = testDomain;
await axios.get(`https://${address}:${port}`, { await axios.get(`https://${address}:${port}`, {
headers: { headers: {
Host: testDomain Host: testDomain
}, },
timeout: config.timeout, timeout: this.config.timeout,
validateStatus: status => status < 500 validateStatus: status => status < 500
}); });
} }
console.log(`Node ${address}:${port} is good.`); this.message(`Node ${address}:${port} is good.`);
return true; return true;
} catch (e) { } catch (e) {
console.log(`Node ${address}:${port} Failed in checking ${currentTestDomain} ${i}: ${e.toString()}`); this.message(`Node ${address}:${port} Failed in checking ${currentTestDomain} ${i}: ${e.toString()}`);
} }
} }
console.log(`Node ${address}:${port} is bad.`); console.log(`Node ${address}:${port} is bad.`);
return false; return false;
} }
async checkRecord(recordInfo: DomainRecordInfo) {
async function checkRecord(recordInfo: DomainRecordInfo) {
const record = recordInfo.record; const record = recordInfo.record;
console.log(`Checking record ${record.RR}.${config.domain} ${record.Value}:${recordInfo.port} with old status of ${record.Status}.`) this.message(`${this.id} => Checking record ${record.RR}.${this.config.domain} ${record.Value}:${recordInfo.port} with old status of ${record.Status}.`)
const status = record.Status; const status = record.Status;
const targetStatus = (await checkNode(record.Value, recordInfo.port)) ? "ENABLE" : "DISABLE"; const targetStatus = (await this.checkNode(record.Value, recordInfo.port)) ? "ENABLE" : "DISABLE";
if (status != targetStatus) { if (status != targetStatus) {
console.log(`Changing record status of ${record.RR}.${config.domain} ${record.Value}:${recordInfo.port} from ${status} to ${targetStatus}.`); this.message(`Changing record status of ${record.RR}.${this.config.domain} ${record.Value}:${recordInfo.port} from ${status} to ${targetStatus}.`);
await client.request("SetDomainRecordStatus", { await this.client.request("SetDomainRecordStatus", {
RecordId: record.RecordId, RecordId: record.RecordId,
Status: targetStatus Status: targetStatus
}, requestOption); }, requestOption);
} }
}
async start() {
this.message(`Started.`);
const records = await this.getRecords();
await Promise.all(records.map(r => {
return this.checkRecord(r);
}));
this.message(`Finished.`);
}
} }
async function run() { async function run() {
console.log(`Started.`); const checker = new Checker(config);
const records = await getRecords(); await checker.start();
await Promise.all(records.map(checkRecord));
console.log(`Finished.`);
} }
async function main() { async function main() {
config = YAML.parse(await fs.promises.readFile("./config.yaml", "utf8")); config = YAML.parse(await fs.promises.readFile("./config.yaml", "utf8"));
client = new Aliyun(config.aliyun);
cdnRecordsRegex = config.cdnRecords.map(m => new RegExp(m.match));
//await run(); //await run();
(new CronJob(config.cronString, run, null, true, "Asia/Shanghai", null, true)).start(); (new CronJob(config.cronString, run, null, true, "Asia/Shanghai", null, true)).start();
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment