Skip to content

Commit

Permalink
Merge pull request #22 from gunnargrosch/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
gunnargrosch authored Mar 16, 2021
2 parents 08ff4c5 + d643638 commit 64752bf
Showing 1 changed file with 104 additions and 61 deletions.
165 changes: 104 additions & 61 deletions lib/failure.js
Original file line number Diff line number Diff line change
@@ -1,94 +1,137 @@
'use strict'
const aws = require('aws-sdk')
const ssm = new aws.SSM()
const fetch = require('node-fetch')
const childProcess = require('child_process')
const Mitm = require('mitm')
"use strict";
const aws = require("aws-sdk");
const ssm = new aws.SSM();
const fetch = require("node-fetch");
const childProcess = require("child_process");
const Mitm = require("mitm");

async function getConfig () {
const defaults = {
isEnabled: false
var mitm = null;

function clearMitm() {
if (mitm != null) {
mitm.disable();
}
}

async function getConfig() {
const defaults = {
isEnabled: false,
};
if (process.env.FAILURE_APPCONFIG_CONFIGURATION) {
try {
if (process.env.AWS_APPCONFIG_EXTENSION_HTTP_PORT) {
var appconfigPort = process.env.AWS_APPCONFIG_EXTENSION_HTTP_PORT
var appconfigPort = process.env.AWS_APPCONFIG_EXTENSION_HTTP_PORT;
} else {
var appconfigPort = 2772
var appconfigPort = 2772;
}
const url = 'http://localhost:' + appconfigPort + '/applications/' + process.env.FAILURE_APPCONFIG_APPLICATION + '/environments/' + process.env.FAILURE_APPCONFIG_ENVIRONMENT + '/configurations/' + process.env.FAILURE_APPCONFIG_CONFIGURATION
const response = await fetch(url)
const json = await response.json()
return json
const url =
"http://localhost:" +
appconfigPort +
"/applications/" +
process.env.FAILURE_APPCONFIG_APPLICATION +
"/environments/" +
process.env.FAILURE_APPCONFIG_ENVIRONMENT +
"/configurations/" +
process.env.FAILURE_APPCONFIG_CONFIGURATION;
const response = await fetch(url);
const json = await response.json();
return json;
} catch (err) {
console.error(err)
return defaults
console.error(err);
return defaults;
}
} else if (process.env.FAILURE_INJECTION_PARAM) {
try {
let params = {
Name: process.env.FAILURE_INJECTION_PARAM
}
let response = await ssm.getParameter(params).promise()
let json = JSON.parse(response.Parameter.Value)
return json
Name: process.env.FAILURE_INJECTION_PARAM,
};
let response = await ssm.getParameter(params).promise();
let json = JSON.parse(response.Parameter.Value);
return json;
} catch (err) {
console.error(err)
return defaults
console.error(err);
return defaults;
}
} else {
return defaults
return defaults;
}
}
var injectFailure = function (fn) {
return async function () {
try {
let config = await getConfig()
let config = await getConfig();

if (config.isEnabled === false || config.failureMode != "denylist") {
clearMitm();
}

if (config.isEnabled === true && Math.random() < config.rate) {
if (config.failureMode === 'latency') {
let latencyRange = config.maxLatency - config.minLatency
let setLatency = Math.floor(config.minLatency + Math.random() * latencyRange)
console.log('Injecting ' + setLatency + ' ms latency.')
await new Promise(resolve => setTimeout(resolve, setLatency))
} else if (config.failureMode === 'exception') {
console.log('Injecting exception message: ' + config.exceptionMsg)
throw new Error(config.exceptionMsg)
} else if (config.failureMode === 'statuscode') {
console.log('Injecting status code: ' + config.statusCode)
let response = { statusCode: config.statusCode }
return response
} else if (config.failureMode === 'diskspace') {
console.log('Injecting disk space: ' + config.diskSpace + ' MB')
childProcess.spawnSync('dd', ['if=/dev/zero', 'of=/tmp/diskspace-failure-' + Date.now() + '.tmp', 'count=1000', 'bs=' + config.diskSpace * 1000])
} else if (config.failureMode === 'denylist') {
console.log('Injecting dependency failure through a network block for denylisted sites: ' + config.denylist)
let mitm = Mitm()
let blRegexs = []
if (config.failureMode === "latency") {
let latencyRange = config.maxLatency - config.minLatency;
let setLatency = Math.floor(
config.minLatency + Math.random() * latencyRange
);
console.log("Injecting " + setLatency + " ms latency.");
await new Promise((resolve) => setTimeout(resolve, setLatency));
} else if (config.failureMode === "exception") {
console.log("Injecting exception message: " + config.exceptionMsg);
throw new Error(config.exceptionMsg);
} else if (config.failureMode === "statuscode") {
console.log("Injecting status code: " + config.statusCode);
let response = { statusCode: config.statusCode };
return response;
} else if (config.failureMode === "diskspace") {
console.log("Injecting disk space: " + config.diskSpace + " MB");
childProcess.spawnSync("dd", [
"if=/dev/zero",
"of=/tmp/diskspace-failure-" + Date.now() + ".tmp",
"count=1000",
"bs=" + config.diskSpace * 1000,
]);
} else if (config.failureMode === "denylist") {
console.log(
"Injecting dependency failure through a network block for denylisted sites: " +
config.denylist
);

// if the global mitm doesn't yet exist, create it now
if (mitm == null) {
mitm = Mitm();
}
mitm.enable();

// attach a handler to filter the configured deny patterns
let blRegexs = [];
config.denylist.forEach(function (regexStr) {
blRegexs.push(new RegExp(regexStr))
})
mitm.on('connect', function (socket, opts) {
let block = false
blRegexs.push(new RegExp(regexStr));
});
mitm.on("connect", function (socket, opts) {
let block = false;
blRegexs.forEach(function (blRegex) {
if (blRegex.test(opts.host)) {
console.log('Intercepted network connection to ' + opts.host)
block = true
console.log("Intercepted network connection to " + opts.host);
block = true;
}
})
});
if (block) {
socket.end()
socket.end();
} else {
socket.bypass()
socket.bypass();
}
})
});

// remove any previously attached handlers, leaving only the most recently added
while (typeof mitm._events.connect != "function") {
mitm.removeListener("connect", mitm._events.connect[0]);
}
}
}
return fn.apply(this, arguments)
return fn.apply(this, arguments);
} catch (ex) {
console.log(ex)
throw ex
console.log(ex);
throw ex;
}
}
}
};
};

module.exports = injectFailure
module.exports = injectFailure;

0 comments on commit 64752bf

Please sign in to comment.