UNPKG

cloudfront-invalidate-cli

Version:

A CLI for invalidating cloudfront distributions that's a bit easier to use than the official AWS CLI.

202 lines (163 loc) 5.92 kB
#!/usr/bin/env node (function () { "use strict"; var usageString = "cf-invalidate [--wait] [--accessKeyId <keyId> --secretAccessKey <key>] -- <distribution> <path>..."; var exampleString = "cf-invalidate -- myDistribution file1 file2 file3"; var AWS = require("aws-sdk"); var yargs = require("yargs"); var fs = require("fs"); var ini = require("ini"); var log = function () {}; var error = function () {}; /** * Function: randomDigits * * Returns a random string of 4 digits. */ function randomDigits() { var n = Math.floor(Math.random() * 1000); return "" + ({ "0": "0000", "1": "000", "2": "00", "3": "0", "4": "", }[("" + n).length]) + n; } /** * Function: loadConfigFile * * Wrapper around invalidate(). Adds AWS sercet and access from .ini config file if its set with --config. */ function loadConfigFile(dist, paths, options, callback) { if (options.config) { fs.readFile(options.config, {encoding: 'utf8'}, function(err, contents) { if (err) { callback(err); return; } var config = ini.parse(contents); if (config && config.default) { options.accessKeyId = config.default.access_key; options.secretAccessKey = config.default.secret_key; } if (!options.secretAccessKey || !options.accessKeyId) { callback("Config file missing access_key or secret_key"); return; } invalidate(dist, paths, options, callback); }); } else { invalidate(dist, paths, options, callback); } } /** * Function: invalidate * * Invalidates objects on cloudfront. * * Parameters: * dist - Cloudfront distribution ID * paths - An array of pathnames to invalidate * options - Options object * wait - If true, wait until the invalidation is complete. * accessKeyId - If set, use this as the AWS key ID * secretAccessKey - The AWS secret key * callback - Callback */ function invalidate(dist, paths, options, callback) { var cloudfront = new AWS.CloudFront(); if (options.accessKeyId) { cloudfront.config.update({ accessKeyId: options.accessKeyId, secretAccessKey: options.secretAccessKey, }); } paths = paths.map(function (v) { if (v.charAt(0) === "/") { return v; } else { return "/" + v; } }); var callerReference = "cf-invalidate-" + Date.now() + "_" + randomDigits(); cloudfront.createInvalidation({ DistributionId: dist, InvalidationBatch: { CallerReference: callerReference, Paths: { Quantity: paths.length, Items: paths, }, }, }, function (err, res) { if (err) {return callback(err);} var invalidationId = res.Invalidation.Id; if (options.wait) { var i = 0; var iteration = function () { cloudfront.getInvalidation({ DistributionId: dist, Id: invalidationId }, function (err, res) { if (err) {return callback(err);} if (res.Invalidation.Status === "Completed") { return callback(); } else { var nextTry = Math.min(60000, 1000 * Math.pow(2, i++)); log('Invalidation not done yet, next try in ' + nextTry + 'ms.'); setTimeout(function () { iteration(); }, nextTry); } }); }; iteration(); } else { callback(); } }); } if (module === require.main) { log = console.log.bind(console); error = console.error.bind(console); var argv = yargs .usage(usageString) .example(exampleString) .demand(2) .option("accessKeyId", { alias: "i", describe: "AWS Key Id override", }) .option("secretAccessKey", { alias: "k", describe: "AWS Secret Key override", }) .implies("accessKeyId", "secretAccessKey") .implies("secretAccessKey", "accessKeyId") .option("wait", { alias: "w", describe: "If set, wait til the invalidation completes", }) .option("config", { alias: "c", describe: "AWS .ini config file path", }) .argv; loadConfigFile(argv._[0], argv._.slice(1), argv, function (err) { if (err) { error(err); process.exit(1); } if (argv.wait) { log("Invalidation Complete"); } else { log("Invalidation Created"); } }); } else { module.exports = invalidate; } }());