-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcloudflare-load-balance-manager.js
executable file
·163 lines (150 loc) · 4.84 KB
/
cloudflare-load-balance-manager.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env node
const program = require('commander');
const fs = require('fs');
const publicIp = require('public-ip');
const colors = require('colors');
const axios = require('axios');
program
.version(JSON.parse(fs.readFileSync('./package.json')).version, '-v, --version')
.usage('<command> <options>');
// Required
program
.option('--name <name>', 'Cloudflare Load Balancer Name')
.option('--identifier <identifier>', 'Cloudflare Load Balancer Identifier')
.option('--api-key <api>', 'Cloudflare API Key')
.option('--email <email>', 'Cloudflare Email Address');
// Not required
program
.option('--origin-name <name>', 'Origin Name')
.option('--origin-weight <weight>', 'Origin Weight');
// Not required (other)
program
.option('--no-color', 'Disable colors from output');
program
.command('register');
program
.command('deregister');
program
.action(async (cmd, options) => {
console.log("\nStep 1: Setting up environment");
cmd = cmd.toLowerCase();
if (cmd !== "register" && cmd !== "deregister") {
console.log(`✖ Invalid Command: ${cmd}`.red);
return process.exit(1);
} else {
console.log(`✔ Set Command: ${cmd}`.green);
}
const apiKey = options.apiKey;
const email = options.email;
let identifier = options.identifier;
const name = options.name;
console.log(!apiKey ? `✖ No API key specified`.red : `✔ Set API key: ${apiKey}`.green);
console.log(!email ? `✖ No email specified`.red : `✔ Set Email: ${email}`.green);
console.log(!identifier ? `* No identifier specified`.yellow : `✔ Set Identifer: ${identifier}`.green);
console.log(!name ? `* No name specified`.yellow : `✔ Set Name: ${name}`.green);
if (!identifier && !name) {
console.log(`✖ Error: name or identifer required`.red);
}
if (!apiKey || !email || (!identifier && !name)) {
return process.exit(1);
}
console.log("\nStep 2: Getting IP address");
let ipAddress;
try {
ipAddress = await getIPAddress();
console.log(`✔ Got IP address: ${ipAddress}`.green);
} catch (e) {
console.log(`✖ Error getting IP address`.red);
showError(e);
return process.exit(1);
}
console.log("\nStep 3: Getting Cloudflare pool details");
let poolDetails;
let originExistsInPool;
try {
const axiosData = await axios.get(`https://api.cloudflare.com/client/v4/user/load_balancers/pools/${identifier ? identifer : ""}`, {
headers: {
"X-Auth-Email": email,
"X-Auth-Key": apiKey,
"Content-Type": "application/json"
}
});
console.log(`✔ Got Cloudflare pool details`.green);
poolDetails = axiosData.data.result;
if (Array.isArray(poolDetails)) {
poolDetails = poolDetails.find(pool => pool.id === identifier || pool.name === name)
}
if (poolDetails) {
console.log(`✔ Found correct pool`.green);
identifier = poolDetails.id;
} else {
console.log(`✖ Couldn't find correct pool`.red);
return process.exit(1);
}
if (poolDetails.origins.some(origin => origin.address === ipAddress)) {
console.log(`✔ Found correct origin within pool`.green);
originExistsInPool = true;
} else {
console.log(`* Could not find correct origin within pool`.yellow);
originExistsInPool = false;
}
} catch (e) {
console.log(`✖ Error getting Cloudflare pool details`.red);
showError(`Status Code\n${e.response.status}\n\nData\n${JSON.stringify(e.response.data, null, 4)}`);
return process.exit(1);
}
console.log(`\nStep 4: ${capitalizeFirstLetter(cmd)}ing instance in Cloudflare pool`);
let updatedPoolOrigins = [...poolDetails.origins];
if (!originExistsInPool) {
console.log(`➜ Adding instance to pool`.gray);
updatedPoolOrigins.push({
name: options.originName || ipAddress.replace(/\./g, "_"),
address: ipAddress,
enabled: cmd === "register",
weight: 1.0
});
} else {
console.log(`➜ Updating pool instances`.gray);
updatedPoolOrigins = updatedPoolOrigins.map(origin => {
if (origin.address === ipAddress) {
return {
...origin,
enabled: cmd === "register",
};
} else {
return origin;
}
});
}
try {
const axiosData = await axios.put(`https://api.cloudflare.com/client/v4/user/load_balancers/pools/${identifier}`, {
name: poolDetails.name,
origins: updatedPoolOrigins,
check_regions: poolDetails.check_regions
}, {
headers: {
"X-Auth-Email": email,
"X-Auth-Key": apiKey,
"Content-Type": "application/json"
}
});
console.log(`✔ Successfully updated Cloudflare pool`.green);
} catch (e) {
console.log(`✖ Error updating Cloudflare pool`.red);
showError(`Status Code\n${e.response.status}\n\nData\n${JSON.stringify(e.response.data, null, 4)}`);
return process.exit(1);
}
});
program
.parse(process.argv);
function getIPAddress() {
return publicIp.v4();
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function showError(err) {
console.log("\n\n\n\n\n\n");
console.error("Error: ");
console.error(err);
}