-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
executable file
·131 lines (123 loc) · 3.78 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env node
const fs = require("fs");
const {Resolver} = require("dns").promises;
const resolver = new Resolver();
const {parseAsync} = require("json2csv");
const {URL} = require("url");
const cliProgress = require("cli-progress");
const pjson = require('./package.json');
const {AWS, GCP, Azure} = require("./providers");
const aws = new AWS();
const gcp = new GCP();
const azure = new Azure();
process.on("uncaughtException", die);
require("yargs")
.command("file <filename>", "lookup hosts in specified file", () => {},
async (argv) => {
if (!fs.existsSync(argv.filename)) {
return die(`File '${argv.filename}' not found.`);
}
const fileContents = fs.readFileSync(argv.filename).toString();
const hostnameLines = fileContents.split("\n");
let results = [];
const bar = new cliProgress.SingleBar({etaBuffer: 1000}, cliProgress.Presets.shades_classic);
bar.start(hostnameLines.length, 0);
let idx = 0;
for (let hostname of hostnameLines) {
const result = await resolve(hostname);
results = results.concat(result);
bar.increment();
}
bar.stop();
await outputHostnameResults(argv, results);
})
.command("host <hostname>", "lookup specified hostname", () => {},
async (argv) => {
const result = await resolve(argv.hostname);
await outputHostnameResults(argv,result);
})
.demandCommand(1, "You must specify at least one command")
.options({
json: {
describe: "Formats output as json",
boolean: true
},
csv: {
describe: "Formats the output as CSV",
boolean: true
},
human: {
describe: "Format the output for human reading (tabs)",
boolean: true
}
})
.strict()
.version(pjson.version)
.fail((msg, error, yargs) => {
if (error) {
console.error(`Error: ${error}`);
}
else {
console.error(msg);
yargs.showHelp();
}
process.exit(1);
})
.argv;
async function outputHostnameResults(argv, results){
const humanOutput = (argv.csv == null);
if (argv.json) {
console.log(results);
}
else if (humanOutput) {
console.table(results);
}
else {
try {
const fields = ["hostname", "address", "provider"];
const opts = {fields};
const csv = await parseAsync(results, opts);
console.log(csv);
}
catch (err) {
return die(err);
}
}
}
async function resolve(hostnameOrURL) {
let hostname = hostnameOrURL;
let addresses = [];
try {
const url = new URL(hostnameOrURL);
hostname = url.hostname;
}
catch {}
try {
addresses = await resolver.resolve4(hostname);
const results = [];
for (let address of addresses) {
const isAWS = await aws.checkAddresses(address);
const isAzure = (!isAWS && await azure.checkAddresses(address));
const isGCP = (!isAWS && !isAzure && await gcp.checkAddresses(address));
let provider = "unknown";
if (isAWS) {
provider = "amazon";
}
else if (isAzure) {
provider = "azure";
}
else if (isGCP) {
provider = "google";
}
results.push({hostname, address, provider});
}
return results;
}
catch (err) {
return [{hostname, address: "unknown", provider: "unknown"}];
}
}
function die(error) {
console.log(error);
process.exit(-1);
}