ui/scripts/aws/update-data

203 lines
4.3 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* This script reads the AWS region data from GitHub (the AWS SDK project) and
* checks the regions against the amazon.js file.
*
* It will update this file with the latest regions if there are changes (regions added or removed)
*
*/
const fs = require('fs');
const path = require('path');
console.log('Updating EC2 and EKS region lists');
console.log('=================================');
console.log('');
const SCRIPT = process.argv[1];
const DIR = path.resolve(SCRIPT, '../../..');
const PARTITIONS = ['aws', 'aws-us-gov', 'aws-cn'];
const ENDPOINTS_URL = 'https://raw.githubusercontent.com/boto/botocore/develop/botocore/data/endpoints.json';
const JS_FILE = path.resolve(DIR, 'lib/shared/addon/utils/amazon.js');
const request = require('request');
function cleanArrayItem(item) {
item = item.trim();
if (item.startsWith('\'')) {
item = item.substr(1);
}
if (item.endsWith(',')) {
item = item.slice(0, -1);
}
if (item.endsWith('\'')) {
item = item.slice(0, -1);
}
return item;
}
function readExisting(name) {
const data = fs.readFileSync(JS_FILE).toString();
const items = [];
let processing = false;
let done = false;
data.split(/\r?\n/).forEach(line => {
if (!done) {
if (!processing) {
if (line.includes(`export const ${ name } = [`)) {
processing = true;
}
} else {
if (line === '];') {
processing = false;
done = true;
} else {
items.push(cleanArrayItem(line.trim()));
}
}
}
});
return items;
}
function patchRegions(key, latest) {
const data = fs.readFileSync(JS_FILE).toString();
const items = [];
const out = [];
let processing = false;
let done = false;
data.split(/\r?\n/).forEach(line => {
if (!done) {
if (!processing) {
if (line.includes(`export const ${ key } = [`)) {
processing = true;
}
out.push(line);
} else {
if (line === '];') {
processing = false;
done = true;
// We've skipped the existing list - now write the new list
latest.forEach((r) => {
out.push(` '${ r }',`);
});
out.push(line);
} else {
items.push(cleanArrayItem(line.trim()));
}
}
} else {
out.push(line);
}
});
// Write the file back out;
fs.writeFileSync(JS_FILE, out.join('\n'));
}
// List regions in a partition
function listRegions(endpoints, partition, svc) {
const p = endpoints.partitions.find((p => p.partition === partition));
if (!p) {
console.error(`Can not find partition ${ partition }`);
return;
}
const regions = [];
Object.keys(p.services?.[svc]?.endpoints || {}).forEach((r) => {
const v = p.services[svc].endpoints[r];
if (!v.deprecated) {
regions.push(r);
// console.log(` ${ r }`);
}
});
regions.sort();
return regions;
}
function checkService(endpoints, svc, key) {
const latest = [];
console.log(`Checking regions for ${ svc }`);
PARTITIONS.forEach((p) => latest.push(...listRegions(endpoints, p, svc)));
const existing = readExisting(key);
const latestMap = {};
const existingMap = {};
latest.forEach((r) => latestMap[r] = true);
existing.forEach((r) => existingMap[r] = true);
let changes = false;
latest.forEach((r) => {
if (!existingMap[r]) {
console.log(' + new region ' + r);
changes = true;
}
});
existing.forEach((r) => {
if (!latestMap[r]) {
console.log(' - removed region ' + r);
changes = true;
}
});
// Patch the changes
if (changes) {
patchRegions(key, latest);
} else {
console.log(' No region changes');
}
console.log('');
return changes;
}
request(ENDPOINTS_URL, function (error, res, body) {
if (error) {
console.error('Could not fetch endpoints data');
process.exit(1);
}
if (res.statusCode !== 200) {
console.error(`Could not fetch endpoints data - status ${ res.statusCode } ${ res.statusMessage }`);
process.exit(2);
}
try {
const endpoints = JSON.parse(body);
checkService(endpoints, 'eks', 'EKS_REGIONS');
checkService(endpoints, 'ec2', 'REGIONS');
} catch (e) {
console.error('Error parsing and processing data');
console.error(e);
process.exit(3);
}
});