Commit b7b25e16 authored by nanahira's avatar nanahira

check cdn mapping nodes

parent 8aee42aa
Pipeline #330 failed with stages
in 2 minutes and 19 seconds
...@@ -47,13 +47,15 @@ interface DomainRecord { ...@@ -47,13 +47,15 @@ interface DomainRecord {
Remark: string; Remark: string;
} }
let config: Config;
interface DomainRecordInfo { interface DomainRecordInfo {
record: DomainRecord; record: DomainRecord;
port: number; port: number;
isCDN: boolean;
good: boolean;
} }
let config: Config;
const requestOption = { const requestOption = {
method: "POST" method: "POST"
} }
...@@ -73,12 +75,26 @@ class Checker { ...@@ -73,12 +75,26 @@ class Checker {
private message(msg: string) { private message(msg: string) {
console.log(`${this.id} => ${msg}`); console.log(`${this.id} => ${msg}`);
} }
getRecordPrefix(m: DomainRecord) {
if (!m.Value.endsWith(this.config.domain)) {
return null;
}
return m.Value.slice(0, m.Value.length - 1 - this.config.domain.length);
}
isCDNRecord(m: DomainRecord) {
const valuePrefix = this.getRecordPrefix(m);
return valuePrefix && _.any(this.cdnRecordsRegex, r => !!valuePrefix.match(r));
}
getRecordPattern(recordInfo: DomainRecordInfo) {
const record = recordInfo.record;
return `${record.RR}.${this.config.domain} => ${record.Value}:${recordInfo.port}`;
}
async getRecords(): Promise<DomainRecordInfo[]> { async getRecords(): Promise<DomainRecordInfo[]> {
this.message(`Fetching domain records of ${config.domain}.`) this.message(`Fetching domain records of ${this.config.domain}.`)
const res: DomainRecordInfo[] = []; const res: DomainRecordInfo[] = [];
for (let i = 1; ; ++i) { for (let i = 1; ; ++i) {
const ret: DomainRecordReturnResult = await this.client.request("DescribeDomainRecords", { const ret: DomainRecordReturnResult = await this.client.request("DescribeDomainRecords", {
DomainName: config.domain, DomainName: this.config.domain,
PageNumber: i, PageNumber: i,
PageSize: 500, PageSize: 500,
}, requestOption); }, requestOption);
...@@ -87,17 +103,12 @@ class Checker { ...@@ -87,17 +103,12 @@ class Checker {
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(this.cdnRecordsRegex, r => !!m.RR.match(r)) && _.every(this.cdnRecordsRegex, r => { return m.RR && m.Type === "CNAME" && _.any(this.cdnRecordsRegex, r => !!m.RR.match(r))
if (!m.Value.endsWith(config.domain)) {
return true;
}
const valuePrefix = m.Value.slice(0, m.Value.length - 1 - config.domain.length);
return !valuePrefix.match(r);
});
})) { })) {
const port = _.find(config.cdnRecords, r => record.RR.match(r.match)).port; const port = _.find(this.config.cdnRecords, r => record.RR.match(r.match)).port;
this.message(`Found record ${record.RR}.${config.domain} => ${record.Value}:${port}.`); const isCDN = this.isCDNRecord(record);
res.push({record, port}); this.message(`Found record ${record.RR}.${this.config.domain} => ${record.Value}:${port}.`);
res.push({record, port, isCDN, good: false});
} }
} }
return res; return res;
...@@ -127,11 +138,27 @@ class Checker { ...@@ -127,11 +138,27 @@ class Checker {
} }
async checkRecord(recordInfo: DomainRecordInfo) { async checkRecord(recordInfo: DomainRecordInfo) {
const record = recordInfo.record; const record = recordInfo.record;
this.message(`Checking record ${record.RR}.${this.config.domain} ${record.Value}:${recordInfo.port} with old status of ${record.Status}.`) this.message(`Checking record ${this.getRecordPattern(recordInfo)} with old status of ${record.Status}.`)
const good = await this.checkNode(record.Value, recordInfo.port);
await this.handleRecordResult(recordInfo, good);
}
async checkCDNRecord(recordInfo: DomainRecordInfo, nonCDNRecords: DomainRecordInfo[]) {
const record = recordInfo.record;
this.message(`Checking CDN record ${this.getRecordPattern(recordInfo)} with old status of ${record.Status}.`)
const valuePrefix = this.getRecordPrefix(record);
const good = _.any(nonCDNRecords, r => {
return r.record.RR === valuePrefix && r.good;
});
this.message(`CDN Record ${this.getRecordPattern(recordInfo)} is ${good ? "good" : "bad"}.`);
await this.handleRecordResult(recordInfo, good);
}
async handleRecordResult(recordInfo: DomainRecordInfo, good: boolean) {
const record = recordInfo.record;
const status = record.Status; const status = record.Status;
const targetStatus = (await this.checkNode(record.Value, recordInfo.port)) ? "ENABLE" : "DISABLE"; recordInfo.good = good;
const targetStatus = good ? "ENABLE" : "DISABLE";
if (status != targetStatus) { if (status != targetStatus) {
this.message(`Changing record status of ${record.RR}.${this.config.domain} ${record.Value}:${recordInfo.port} from ${status} to ${targetStatus}.`); this.message(`Changing record status of ${this.getRecordPattern(recordInfo)} from ${status} to ${targetStatus}.`);
await this.client.request("SetDomainRecordStatus", { await this.client.request("SetDomainRecordStatus", {
RecordId: record.RecordId, RecordId: record.RecordId,
Status: targetStatus Status: targetStatus
...@@ -141,9 +168,14 @@ class Checker { ...@@ -141,9 +168,14 @@ class Checker {
async start() { async start() {
this.message(`Started.`); this.message(`Started.`);
const records = await this.getRecords(); const records = await this.getRecords();
await Promise.all(records.map(r => { const nonCDNRecords = records.filter(m => !m.isCDN);
const CDNRecords = records.filter(m => !!m.isCDN);
await Promise.all(nonCDNRecords.map(r => {
return this.checkRecord(r); return this.checkRecord(r);
})); }));
await Promise.all(CDNRecords.map(r => {
return this.checkCDNRecord(r, nonCDNRecords);
}));
this.message(`Finished.`); this.message(`Finished.`);
} }
} }
......
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