UNPKG

mecano

Version:

Common functions for system deployment.

226 lines (219 loc) 7.29 kB
// Generated by CoffeeScript 1.7.1 var child, conditions, each, execute, misc; each = require('each'); misc = require('./misc'); conditions = require('./misc/conditions'); child = require('./misc/child'); execute = require('./execute'); module.exports = function(goptions, options, callback) { var finish, result, _ref; _ref = misc.args(arguments), goptions = _ref[0], options = _ref[1], callback = _ref[2]; result = child(); finish = function(err, written) { if (callback) { callback(err, written); } return result.end(err, written); }; misc.options(options, function(err, options) { var executed; if (err) { return callback(err); } executed = 0; return each(options).parallel(goptions.parallel).on('item', function(options, next) { var cmd, cmd_add, cmd_modify, cmd_remove, crules, do_cmds, do_list, do_position, do_save; crules = []; cmd = function(cmd, rule) { if (rule.protocol) { cmd += " -p " + rule.protocol; } if (rule.source) { cmd += " -s " + rule.source; } if (rule.destination) { cmd += " -d " + rule.destination; } if (rule.target) { cmd += " -j " + rule.target; } if (rule.dport) { cmd += " --dport " + rule.dport; } if (rule.sport) { cmd += " --sport " + rule.sport; } if (rule.state) { cmd += " -m state --state " + rule.state; } if (rule.comment) { cmd += " -m comment --comment \"" + rule.comment + "\""; } return cmd; }; cmd_add = function(rule) { return cmd("iptables -I " + rule.chain + " " + rule.rulenum, rule); }; cmd_modify = function(rule) { return cmd("iptables -R " + rule.chain + " " + rule.rulenum, rule); }; cmd_remove = function(rule) { return "iptables -D " + rule.chain + " " + rule.rulenum; }; do_list = function() { var chains; chains = {}; return execute({ cmd: "iptables -L --line-numbers -nv", ssh: options.ssh, log: options.log, stdout: options.stdout, stderr: options.stderr }, function(err, executed, stdout) { var chain, columns, i, ichain, k, line, match, others, rule, v, _i, _j, _k, _len, _len1, _len2, _ref1, _ref2; if (err) { return next(err); } ichain = 0; chain = null; _ref1 = stdout.split(/\r\n|[\n\r\u0085\u2028\u2029]/g); for (i = _i = 0, _len = _ref1.length; _i < _len; i = ++_i) { line = _ref1[i]; if (ichain === 0) { match = /^Chain\s+(\w+)\s+.*$/.exec(line); if (!match) { return next(new Error("Invalid output: " + (JSON.stringify(stdout)))); } chain = match[1]; ichain++; continue; } if (ichain === 1) { ichain++; continue; } if (/^\s*$/.test(line)) { ichain = 0; continue; } columns = line.split(/\ +/); rule = { chain: chain }; _ref2 = ['rulenum', 'packets', 'bytes', 'target', 'protocol', 'options', 'in-interface', 'out-interface', 'source', 'destination']; for (i = _j = 0, _len1 = _ref2.length; _j < _len1; i = ++_j) { k = _ref2[i]; rule[k] = columns[i]; } others = columns.slice(10); for (i = _k = 0, _len2 = others.length; _k < _len2; i = ++_k) { v = others[i]; if (v === '/*') { rule.comment = ''; while ((v = others[++i]) !== '*/') { rule.comment += ' ' + v; } } else if (match = /^dpt:(\d+)$/.exec(v)) { rule.dport = match[1]; } else if (v === '--state') { rule.state = others[++i]; } } crules.push(rule); } if (crules.length === 0) { return next(new Error("IPTables rules not loaded, (re)start iptables")); } return do_position(); }); }; do_position = function() { var add_properties, crule, rule, _i, _j, _len, _len1, _ref1; _ref1 = options.rules; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { rule = _ref1[_i]; if (rule.rulenum == null) { rule.rulenum = { chain: 'INPUT', target: 'ACCEPT', 'in-interface': 'lo' }; } if (typeof rule.rulenum !== 'object') { continue; } add_properties = misc.array.intersect(misc.iptables.add_properties, Object.keys(rule.rulenum)); for (_j = 0, _len1 = crules.length; _j < _len1; _j++) { crule = crules[_j]; if (misc.object.equals(rule.rulenum, crule, add_properties)) { rule.rulenum = '' + (parseInt(crule.rulenum, 10) + 1); break; } } if (!/\d+/.test(rule.rulenum)) { if (typeof options.log === "function") { options.log("No matching rule number, default to 1"); } rule.rulenum = 1; } } return do_cmds(); }; do_cmds = function() { var add_properties, cmds, create, crule, rule, _i, _j, _len, _len1, _ref1; cmds = []; _ref1 = options.rules; for (_i = 0, _len = _ref1.length; _i < _len; _i++) { rule = _ref1[_i]; create = true; add_properties = misc.array.intersect(misc.iptables.add_properties, Object.keys(rule)); for (_j = 0, _len1 = crules.length; _j < _len1; _j++) { crule = crules[_j]; if (misc.object.equals(rule, crule, add_properties)) { create = false; if (!misc.object.equals(rule, crule, misc.iptables.modify_properties)) { cmds.push(cmd_modify(rule)); } } } if (create) { cmds.push(cmd_add(rule)); } } if (!cmds.length) { return next(); } return execute({ cmd: cmds.join(';'), ssh: options.ssh, log: options.log, stdout: options.stdout, stderr: options.stderr }, function(err, executed, stdout) { if (err) { return next(err); } return do_save(); }); }; do_save = function() { return execute({ cmd: "service iptables save", ssh: options.ssh, log: options.log, stdout: options.stdout, stderr: options.stderr }, function(err, executed, stdout) { if (!err) { executed++; } return next(err); }); }; return conditions.all(options, next, do_list); }).on('both', function(err) { return finish(err, executed); }); }); return result; };