dashboard/scripts/azure/update-data

209 lines
4.9 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* This script reads the Azure website and updates our hard-coded file it needed
*/
const fs = require('fs');
const path = require('path');
const axios = require('axios');
console.log('Updating Azure regions in Availability Zones');
console.log('============================================');
console.log('');
const SCRIPT = process.argv[1];
const DIR = path.resolve(SCRIPT, '../../..');
const ENDPOINTS_URL = 'https://learn.microsoft.com/en-us/azure/reliability/regions-list';
const TS_FILE = path.resolve(DIR, 'pkg/aks/util/aks-regions.ts');
const COLUMN_REGEX = /<td>(.*)<\/td>/;
const US_GOV = 'usgov';
function findRegions(body) {
const regions = [];
let inTable = false;
let inRow = false;
let inColumn = false;
let row = [];
let column = ''
body.split('\n').forEach((line) => {
line = line.trim();
if (line.indexOf('<table') >= 0) {
inTable = true;
} else if (inTable) {
if (line.indexOf('</table>') >= 0) {
inTable = false;
} else if (inRow) {
if (!inColumn && line.indexOf('<td>') === 0) {
inColumn = true;
column = line;
if (line.endsWith('</td>')) {
row.push(column);
inColumn = false;
}
} else if (inColumn && line.endsWith('</td>')) {
column += line;
row.push(column);
inColumn = false;
} else if (line.indexOf('</tr>') === 0) {
inRow = false;
if (row.length === 5) {
if (!row[0].startsWith('<td><img') && !row[1].startsWith('<td></td>')) {
const m = row[0].match(COLUMN_REGEX);
if (m && m.length === 2) {
let region = m[1].toLowerCase();
region = region.replaceAll(' ', '');
regions.push(region);
}
}
}
}
} else if (!inRow && line.indexOf('<tr>') == 0) {
inRow = true;
row = [];
}
}
});
return regions.sort();
}
function cleanItem(item) {
const p = item.split(':');
if (p.length === 2) {
return p[0];
}
return undefined;
}
function readExisting() {
const data = fs.readFileSync(TS_FILE).toString();
const items = [];
let processing = false;
let done = false;
data.split(/\r?\n/).forEach(line => {
line = line.trim();
if (!done) {
if (!processing) {
if (line.startsWith('export const ')) {
processing = true;
}
} else {
if (line === '} as any;') {
processing = false;
done = true;
} else {
const r = cleanItem(line);
if (r) {
items.push(r);
}
}
}
}
});
return items.sort();
}
function writeNewFile(regions) {
let lines = ['export const regionsWithAvailabilityZones = {'];
let maxLength = 1;
regions.forEach((r) => {
if (r.length > maxLength) {
maxLength = r.length + 1; // Add room for :
}
});
regions.forEach((r) => {
const key = `${r}:`.padEnd(maxLength);
lines.push(` ${ key } true,`)
});
lines.push('} as any;');
lines.push('');
fs.writeFileSync(TS_FILE, lines.join('\n'));
}
const existing = readExisting();
axios.get(ENDPOINTS_URL, { responseType: 'document' }).then((res) => {
if (res.status !== 200 || !res.data) {
console.error(`Could not fetch Azure data - status ${ res.statusCode } ${ res.statusMessage }`);
process.exit(1);
}
const regions = findRegions(res.data);
const govRegions = existing.filter((r) => r.startsWith(US_GOV));
const existingCount = existing.length;
if (regions.length === 0) {
console.error('Could not fetch data from Azure - no regions found');
process.exit(2);
}
console.log(`Existing regions in our codebase: ${ existingCount - govRegions.length } (Excluding US Government regions)`);
console.log(existing);
console.log('');
console.log(`Regions from Azure: ${ regions.length }`);
console.log(regions);
console.log('');
const removed = [];
existing.forEach((r) => {
if (r.startsWith(US_GOV)) {
regions.push(r);
} else if (!regions.includes(r)) {
removed.push(r);
}
});
console.log('');
console.log(`US Government regions to be retained: ${ govRegions.join(', ') }`);
console.log('');
if (removed.length) {
console.log(`These region(s) have been removed: ${ removed.join(', ') }`);
}
const added = [];
regions.forEach((r) => {
if (!existing.includes(r)) {
added.push(r);
}
});
if (added.length) {
console.log(`These region(s) have been added: ${ added.join(', ') }`);
}
if (added.length || removed.length) {
// Sort the regions (needs a resort if we added back in usgov regions)
writeNewFile(regions.sort());
console.log('');
console.log(`Regions updated from ${ existingCount } to ${ regions.length }`);
console.log('');
} else {
console.log('No changes to the Azure region data');
}
});