Init
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-03-05 03:24:08 +08:00
commit 6e5e5f1683
10 changed files with 629 additions and 0 deletions

21
src/bgpq4.ts Normal file
View File

@ -0,0 +1,21 @@
import { execFile } from "node:child_process";
import LRUCache from "lru-cache";
const cache = new LRUCache({
max: 500,
ttl: 1000 * 60 * 5,
});
export default async function bgpq4(asSet: string): Promise<number[]> {
if (cache.has(asSet)) return cache.get(asSet) as number[];
const answer: { as: number[] } = await new Promise((resolve) => {
execFile("bgpq4", ["-tjl", "as", "-L", "6", asSet], (error, stdout) => {
if (error) {
throw error;
}
resolve(JSON.parse(stdout));
});
});
cache.set(asSet, answer.as);
return answer.as;
}

116
src/index.ts Normal file
View File

@ -0,0 +1,116 @@
import bgpq4 from "./bgpq4";
import fs from "node:fs";
import YAML from "yaml";
import axios from "axios";
import { env } from "node:process";
const main = async () => {
const config: {
"MNT-BY": string[];
"TECH-C": string[];
"ADMIN-C": string[];
"AS-SETS": {
[asSetsName: string]: {
group: [groupName: string][];
expect: number[];
include: string[];
remarks: string[];
};
};
members: {
[member: string]: [groupName: string][];
}[];
} = YAML.parse(fs.readFileSync("../config.yaml", "utf8"));
const asSets: {
"AS-SET": string;
"MNT-BY": string[];
"TECH-C": string[];
"ADMIN-C": string[];
members: number[];
remarks: string[];
include: string[];
}[] = [];
console.log("INFO: start AS-SETS generation.");
let i = 1;
for (let asSetName in config["AS-SETS"]) {
console.log(
`INFO: generating AS-SETS <${asSetName}>... (${i}/${
Object.keys(config["AS-SETS"]).length
})\n`
);
let members = await Promise.all(
config.members.map(async (member) => {
const setName = Object.keys(member)[0];
const setGroup = Object.values(member)[0];
if (
config["AS-SETS"][asSetName].group.filter(
(e) => setGroup.includes(e) || (e as any) === "*"
).length == 0
)
return undefined;
const answer = await bgpq4(setName);
console.log("Add", setName, answer, "to", asSetName);
return answer.filter(
(as) => !(config["AS-SETS"][asSetName].expect ?? [0]).includes(as)
);
})
);
config["AS-SETS"][asSetName].remarks.push(
`Generated by git.186526.xyz/186526/net186-as-set.`
);
config["AS-SETS"][asSetName].remarks.push(
`Updated on ${new Date().toISOString()}.`
);
asSets.push({
"AS-SET": asSetName,
"MNT-BY": config["MNT-BY"],
"TECH-C": config["TECH-C"],
"ADMIN-C": config["ADMIN-C"],
remarks: config["AS-SETS"][asSetName].remarks,
members: Array.from(new Set(members.flat(Infinity))).filter(
Boolean
) as number[],
include: config["AS-SETS"][asSetName].include,
});
i++;
console.log("");
}
const answer = asSets.map((k) => {
return `as-set: ${k["AS-SET"]}
${k["MNT-BY"].map((k) => `mnt-by: ${k}`).join("\n")}
${k["TECH-C"].map((k) => `tech-c: ${k}`).join("\n")}
${k["ADMIN-C"].map((k) => `admin-c: ${k}`).join("\n")}
${k.remarks.map((k) => `remarks: ${k}`).join("\n")}
${k.members.map((k) => `members: AS${k}`).join("\n")}${(k.include ?? []).map(
(k) => `\nmembers: ${k}`
)}
source: RIPE\npassword: ${env["RIPE_PASSWORD"]}\n
`;
});
console.log("INFO: sending update to RIPE Syncupdates...");
const update = await axios.post(
"https://syncupdates.db.ripe.net",
`DATA=${answer.join("\n")}`,
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "net186-as-set/1.0.0 axios curl",
},
}
);
console.log("INFO: Updates finished.\n");
console.log(update.data);
};
main();