diff --git a/.gitignore b/.gitignore index de2acfdf1..484a31054 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ src/**/Makefile !src/modules/example/Makefile src/dhparam*.txt src/*.dSYM +src/js/node_modules/ src/lua/src/lua src/modules/*.dSYM src/noit_version.h diff --git a/src/Makefile.in b/src/Makefile.in index ac0ce940c..866cf1b94 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -429,6 +429,9 @@ distclean-subdirs: distclean: clean distclean-subdirs rm -f Makefile noit_config.h scripts/noit-config +js/bundle.desc: bundle.proto + protoc -ojs/bundle.desc bundle.proto + bundle: protoc bundle.proto --java_out=java protoc-c bundle.proto --c_out=. diff --git a/src/js/bundle.desc b/src/js/bundle.desc new file mode 100644 index 000000000..4f97508f6 --- /dev/null +++ b/src/js/bundle.desc @@ -0,0 +1,28 @@ + +Á + bundle.proto"˜ +Metric +name (  + +metricType ( +valueDbl ( +valueI64 ( + valueUI64 ( +valueI32 ( + valueUI32 (  +valueStr ( "L +Status + available ( +state ( +duration ( +status ( "& +Metadata +key (  +value ( "y +Bundle +status ( 2.Status +metrics ( 2.Metric +metadata ( 2 .Metadata +period (  +timeout ( B% +com.omniti.reconnoiterB CheckStatus \ No newline at end of file diff --git a/src/js/connection.js b/src/js/connection.js new file mode 100644 index 000000000..d6a7e0441 --- /dev/null +++ b/src/js/connection.js @@ -0,0 +1,432 @@ +/* +Copyright (c) 2010-2015 Circonus, Inc. All rights reserved. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name Circonus, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +var sys = require('sys'), + fs = require('fs'), + net = require('net'), + crypto = require('crypto'), + tls = require('tls'), + loginfo = require('./log'), + EventEmitter = require('events').EventEmitter, + debug = global.debug, + stats = {}; + +var MAX_FRAME_LEN = 65530, + CMD_BUFF_LEN = 4096; + +var nc = function(port,host,creds,cn) { + this.shutdown = false; + this.port = port; + this.host = host; + this.remote = host + ":" + port; + if(! (this.remote in stats)) stats[this.remote] = { + livestream_requests: 0, livestream_in: 0, livestream_out: 0, + data_temp_feed_requests: 0, data_temp_feed_in: 0, data_temp_feed_out: 0, + connects: 0, connections: 0, closes: 0 + }; + this.options = creds; + this.options.host = host; + this.options.port = port; + if(cn) { + this.cn = cn; + this.options.servername = cn; + } + this.channels = {}; +}; + +sys.inherits(nc, EventEmitter); + +function htonl(buf,b) { + buf[0] = (b >> 24) & 0xff; + buf[1] = (b >> 16) & 0xff; + buf[2] = (b >> 8) & 0xff; + buf[3] = b & 0xff; +} +function ntohl(buf) { + return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; +} + +nc.prototype.stop = function() { + this.shutdown = true; + if(this.socket) { + this.socket.end(); + this.socket.destroy(); + } + this.socket = null; +} +nc.prototype.start = function(conncb) { + var parent = this; + this.conncb = conncb; + stats.global.connects++; + stats[parent.remote].connects++; + stats.global.connections++; + stats[parent.remote].connections++; + this.socket = tls.connect(this.options, + function() { + if(parent.socket.authorized == false && + parent.socket.authorizationError != 'SELF_SIGNED_CERT_IN_CHAIN') { + console.log('invalid cert: ' + parent.socket.authorizationError); + throw('invalid cert: ' + parent.socket.authorizationError); + } + parent.remote_cert = parent.socket.getPeerCertificate(); + if(parent.cn && parent.remote_cert.subject.CN != parent.cn) { + throw('invalid cert: CN mismatch'); + } + parent.conncb(parent); + } + ); + this.socket.addListener('error', function(e) { + console.log('noit ('+parent.host+'): '+e); + parent.reverse_cleanup(); + setTimeout(function() { parent.start(parent.conncb); }, 1000); + }); + this.socket.addListener('close', + function() { + stats.global.closes++; + stats[parent.remote].closes++; + stats.global.connections--; + stats[parent.remote].connections--; + if(!parent.socket) console.log('socket closed'); + else if (parent.socket.authorized == false) console.log('invalid cert ('+parent.host+')'); + parent.reverse_cleanup(); + if(!parent.shutdown) { + if(parent.socket) parent.socket.destroy(); + parent.socket = null; + setTimeout(function() { parent.start(parent.conncb); }, 1000); + } + } + ); +}; + +nc.prototype.data_temp_feed = function() { + stats.global.data_temp_feed_requests++; + stats[parent.remote].data_temp_feed_requests++; + this.start(function(parent) { + var b = new Buffer(4); + htonl(b,0x7e66feed); + parent.socket.write(b); + + parent._buf = []; + parent._inprocess = { }; + parent._want = 0; + + parent.socket.addListener('data', function(buffer) { + if(parent.shutdown) return parent.stop(); + var listeners = parent.listeners('jlog'); + if(!listeners || listeners.length == 0) return parent.stop(); + for(var i = 0; i= 3) console.log("livestream -> writing request"); + parent._buf = []; + parent.body_need = 0; + + parent.socket.addListener('data', function(buffer) { + if(debug >= 3) console.log("livestream <- [data]"); + if(parent.shutdown) return parent.stop(); + for(var i = 0; i 0) { + if(parent._buf.length < parent.body_need) break; + var line_buf = parent._buf.splice(0, parent.body_need) + parent.body_need = 0; + + var line = line_buf.map(function(a) { return String.fromCharCode(a) }).join(''); + var tidx = line.indexOf('\t'); + if(tidx > 0) + line = line.substring(0, tidx+1) + parent.host + line.substring(tidx); + if(debug >= 3) console.log("livestream <- " + (tidx > 0 ? line.substring(0, tidx) : "??")); + stats.global.livestream_in++; + stats[parent.remote].livestream_in++; + loginfo.parse(line, function(infos) { + if(infos.constructor !== Array) infos = [infos]; + var i=0; cnt=infos.length; + stats.global.livestream_out += cnt; + stats[parent.remote].livestream_out += cnt; + for(;i= 3) console.log("livestream -> "+info.type+":"+info.id); + // emulate a rouing key: check.uuid_nasty + var account_id = ('circonus_account_id' in info) ? info.circonus_account_id : 0; + var check_id = ('circonus_check_id' in info) ? info.circonus_check_id : 0; + var route = 'check.' + account_id + '.' + check_id + '.' + info.id.replace(/-/g, '').split('').join('.'); + parent.emit('live', uuid, period, { routingKey: route }, info); + if(f && !f({ routingKey: route }, info)) { + parent.stop(); + } + } + } + }); + } + } + }); + }); +}; + +function decode_frame(blist) { + var frame = {} + var hdr = new Buffer(6); /* hdr uint16 + uint32 */ + var i, avail = 0, needed = 0, read_header = false; + for(i=0;i= hdr.length) { /* header size */ + frame.channel_id = hdr.readUInt16BE(0); + frame.command = (frame.channel_id & 0x8000) ? true: false; + frame.channel_id &= 0x7fff; + frame.bufflen = hdr.readUInt32BE(2); + if(frame.bufflen > MAX_FRAME_LEN) { + throw('oversized_frame: ' + frame.bufflen); + } + frame.buff = new Buffer(frame.bufflen); + read_header = true; + break; + } + } + if(!read_header) return null; + if(needed == blist[i].length) { /* we used the whole buffer */ + i++; + needed = 0; + } + var start = needed; + avail = 0; + for(;i 0) { + blist.splice(0, i); + } + if((start+needed) != 0) { + blist[0] = blist[0].slice((start+needed)); + } + return frame; + } + start = 0; + } + return null; +} +nc.prototype.reverse_cleanup = function(conncb) { + var parent = this; + parent.buflist = []; + if(parent.channels) { + for(var channel_id in parent.channels) { + var channel = parent.channels[channel_id]; + if(channel.socket) { + channel.socket.end(); + channel.socket.destroy(); + } + } + parent.channels = {}; + } +} +var CMD_CONNECT = new Buffer('CONNECT', 'utf8'), + CMD_SHUTDOWN = new Buffer('SHUTDOWN', 'utf8'), + CMD_CLOSE = new Buffer('CLOSE', 'utf8'), + CMD_RESET = new Buffer('RESET', 'utf8'); + +function frame_output(channel_id, command, buff) { + var frame = new Buffer(6 + buff.length); + buff.copy(frame, 6, 0, buff.length); + frame.writeUInt16BE((channel_id & 0x7fff) | (command ? 0x8000 : 0), 0); + frame.writeUInt32BE(buff.length, 2); +console.log('send', channel_id, command ? "comm" : "data", buff.length, frame.slice(0,6)); + return frame; +} +function isCmd(buf1, buf2) { + if(buf1.length != buf2.length) return false; + for(var i=0;i 0 ? str.substring(0, tidx) : "??")); + } + p.parse(str, function(infos) { + if(infos.constructor !== Array) infos = [infos]; + var i=0; cnt=infos.length; + p.stats.messages_out += cnt; + for(;i " + + info.type + ":" + info.id); + p.emit('message', str, info); + } + }); + }); + client.on('close', function (e) { + p.stats.closes++; + p.clearHeartbeat(); + p.emit('close'); + }); +}; + +module.exports = fh; diff --git a/src/js/histogram.js b/src/js/histogram.js new file mode 100644 index 000000000..6791dbbf1 --- /dev/null +++ b/src/js/histogram.js @@ -0,0 +1,83 @@ +var BVL1 = 0, BVL2 = 1, BVL3 = 2, BVL4 = 3, + BVL5 = 4, BVL6 = 5, BVL7 = 6, BVL8 = 7, + power_of_ten = [ + 1, 10, 100, 1000, 10000, 100000, 1e+06, 1e+07, 1e+08, 1e+09, 1e+10, + 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, + 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, + 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, + 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, + 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101, 1e+102, 1e+103, 1e+104, 1e+105, 1e+106, 1e+107, 1e+108, 1e+109, + 1e+110, 1e+111, 1e+112, 1e+113, 1e+114, 1e+115, 1e+116, 1e+117, 1e+118, + 1e+119, 1e+120, 1e+121, 1e+122, 1e+123, 1e+124, 1e+125, 1e+126, 1e+127, + 1e-128, 1e-127, 1e-126, 1e-125, 1e-124, 1e-123, 1e-122, 1e-121, 1e-120, + 1e-119, 1e-118, 1e-117, 1e-116, 1e-115, 1e-114, 1e-113, 1e-112, 1e-111, + 1e-110, 1e-109, 1e-108, 1e-107, 1e-106, 1e-105, 1e-104, 1e-103, 1e-102, + 1e-101, 1e-100, 1e-99, 1e-98, 1e-97, 1e-96, + 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, + 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, 1e-79, 1e-78, 1e-77, 1e-76, + 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, + 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, 1e-59, 1e-58, 1e-57, 1e-56, + 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, + 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, 1e-39, 1e-38, 1e-37, 1e-36, + 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, + 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, 1e-19, 1e-18, 1e-17, 1e-16, + 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-09, 1e-08, 1e-07, 1e-06, + 1e-05, 0.0001, 0.001, 0.01, 0.1 + ]; + +var decode_bucket = function(hist, buffer, buffer_len, offset, raw) { + var remaining = buffer_len - offset; + if(remaining < 3) return -1; + var key, + bucket_val = buffer.readInt8(offset), + bucket_exp = buffer.readUInt8(offset + 1), + tgt_type = buffer.readUInt8(offset + 2); + if(tgt_type > BVL8) return -1; + if(remaining < 3 + tgt_type + 1) return -1; + var count = 0; + for(var i=tgt_type;i>=0;i--) { + count += buffer.readUInt8(offset + i + 3) * (Math.pow(2,i*8)); + } + if(raw) { + key = buffer.slice(offset,offset+2).toString('hex'); + } + else { + if(bucket_val > 99 || bucket_val < -99) key = 'NaN'; + else if(bucket_val < 10 && bucket_val > -10) key = '0.0'; + else key = ((bucket_val/10.0) * power_of_ten[bucket_exp]).toString(); + } + hist[key] = count; + return 3 + tgt_type + 1; +}; + +exports.decode = function(b64) { + var raw = false; + if(arguments[1] != undefined) { + if(typeof(arguments[1]) != 'boolean') { + throw ('Invalid non-boolean second argument to histogram.decode'); + } + raw = arguments[1]; + } + + var b = new Buffer(b64, 'base64'), + blen = b.length, + offset = 0, + hist = {}; + + if(b.length < 2) return null; + var cnt = b.readInt16BE(offset); + if(cnt == 0) return hist; + offset += 2; + while(offset < blen && cnt > 0) { + var incr_read = decode_bucket(hist, b, blen, offset, raw); + if(incr_read <= 0) break; + offset += incr_read; + cnt--; + } + return hist; +}; diff --git a/src/js/index.js b/src/js/index.js new file mode 100644 index 000000000..ef7b866e5 --- /dev/null +++ b/src/js/index.js @@ -0,0 +1,6 @@ +exports.log = require('./log'); +exports.connection_set_stats = require('./connection').set_stats; +exports.connection = require('./connection').connection; +exports.firehose = require('./firehose'); +exports.mapper = require('./map_uuid').mapper; +exports.utils = require('./utils'); diff --git a/src/js/log.js b/src/js/log.js new file mode 100644 index 000000000..36eb8129d --- /dev/null +++ b/src/js/log.js @@ -0,0 +1,200 @@ +/* +Copyright (c) 2010-2013 Circonus, Inc. All rights reserved. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name Circonus, Inc. nor the names of its contributors + may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +var sys = require('sys'), + fs = require('fs'), + Histogram = require('./histogram'), + zlib = require('zlib'), + Schema = require('protobuf').Schema, + schema = new Schema(fs.readFileSync(__dirname + "/bundle.desc")), + bundle_protobuf = schema['Bundle']; + +function make_b_parser(step1, step2, step3) { + return function (original, cb) { + step1(original, original, + function(input, original) { + step2(input, original, + function(input, original) { + step3(input, original, cb); + } + ) + } + ); + } +} + +function b64_decode(input, orig, next_step) { + next_step(new Buffer(input.data, 'base64'), orig); +} +function decompress(input, orig, next_step) { + zlib.inflate(input, function(err, inflated) { + next_step(inflated, orig); + }); +} +function identity(input, orig, next_step) { + next_step(input, orig); +} +function read_protobuf(input, orig, next_step) { + var infos = []; + try { + var bobj = bundle_protobuf.parse(input); + if(bobj.status) { + var info = { + type: 'S', + agent: orig.agent, + time: orig.time, + id: orig.id, + check_target: orig.check_target, + check_module: orig.check_module, + check_name: orig.check_name, + circonus_account_id: orig.circonus_account_id, + circonus_check_id: orig.circonus_check_id, + state: bobj.status.state, + availability: bobj.status.available, + duration: bobj.status.duration, + status: bobj.status.status + }; + if(bobj.metadata) { + info.metadata = {}; + bobj.metadata.map(function(o) { info.metadata[o.key] = o.value; }); + } + infos.push(info); + } + if(bobj.metrics) { + var len = bobj.metrics.length; + for(var i=0;i 36) { + var full = info['id']; + info['id'] = full.substring(full.length-36, full.length); + var p1 = full.indexOf('`'); + if(p1 >= 0) { + info['check_target'] = full.substring(0,p1++); + var p2 = full.indexOf('`', p1); + if(p2 >= 0) { + info['check_module'] = full.substring(p1,p2++); + if(p2 < full.length - 36) { + info['check_name'] = full.substring(p2, full.length - 37); + var m = /^c_(\d+)_(\d+)::/.exec(info['check_name']); + if(m) { + info['circonus_account_id'] = m[1]; + info['circonus_check_id'] = m[2]; + } + } + } + } + } +} + +(function () { + var fmts = { + 'C': [ 'agent', 'time', 'id', 'target', 'module', 'name' ], + 'S': [ 'agent', 'time', 'id', 'state', 'availability', 'duration', 'status' ], + 'M': [ 'agent', 'time', 'id', 'metric_name', 'metric_type', 'value' ], + 'B1': [ 'agent', 'time', 'id', 'target', 'module', 'name', 'raw_len', 'data' ], + 'B2': [ 'agent', 'time', 'id', 'target', 'module', 'name', 'raw_len', 'data' ], + 'H1': [ 'agent', 'time', 'id', 'metric_name', 'serialized_histogram' ] + }; + var postprocs = { + 'B1': make_b_parser(b64_decode, decompress, read_protobuf), + 'B2': make_b_parser(b64_decode, identity, read_protobuf), + 'H1': function(original, cb) { + original.histogram = Histogram.decode(original.serialized_histogram); + cb(original); + } + }; + exports.parse = function(str, cb) { + var tidx = str.indexOf('\t'); + var t = tidx > 0 ? str.substring(0, tidx) : str; + var arr = tidx > 0 ? str.substring(tidx+1) : null; + + var fmt = fmts[t], + postproc = postprocs[t], + parts = [], + info = {}; + + if(arr == null) return; + if(arr[arr.length-1] == '\n') arr = arr.substring(0, arr.length-1); + if(fmt != null && arr != null) parts = arr.split("\t"); + if(/^\d+\.\d+$/.test(parts[0])) parts.unshift("unknown"); + if(parts.length > 0 && parts.length > fmt.length) + parts.push(parts.splice(fmt.length-1).join('\t')); + if(fmt == null || parts.length != fmt.length) { + info = {type: 'unknown', data: arr==null ? t : [t,arr].join("\t") }; + if(postproc) postproc(info, cb); + else cb(info); + return; + } + info.type = t; + for(var i=0; i " + p._hb); + p._last_seen_hb = p._hb; + }, p.params.heartbeat * 3 * 1000); + } + this.mq.on('heartbeat', function() { p.handleHeartbeat(); }); + this.mq.on('ready', function () { + var mq = this; + var exchange = p.options.exchange; + if(p.options.type) exchange = mq.exchange(p.options.exchange, p.options); + var q = mq.queue(p.options.queuename || '', function() { + q.bind(exchange, p.options.routing_key); + + q.subscribeRaw({noAck: true}, function (m) { + p.handleHeartbeat(); + m._payload = ''; + m.addListener('data', function (d) { + if(d != null) this._payload += d; + }); + m.addListener('end', function () { + var str = this._payload; + p.stats.messages_in++; + if(debug) { + var tidx = str.indexOf('\t'); + console.log("mq["+p.options.routing_key+"] <- " + + (tidx > 0 ? str.substring(0, tidx) : "??")); + } + p.parse(str, function(infos) { + if(infos.constructor !== Array) infos = [infos]; + var i=0; cnt=infos.length; + p.stats.messages_out += cnt; + for(;i " + + info.type + ":" + info.id); + p.emit('message', m, info); + } + }); + }); + }); + }); + }); +}; + +module.exports = fh; diff --git a/src/js/package.json b/src/js/package.json new file mode 100644 index 000000000..2c519794e --- /dev/null +++ b/src/js/package.json @@ -0,0 +1,17 @@ +{ + "name": "noit", + "version": "0.0.1", + "description": "Noit Connection Utilities", + "main": "index.js", + "scripts": { + "test": "echo \"no test specified\" && exit 0" + }, + "author": "", + "license": "ISC", + "dependencies": { + "protobuf": "^0.11.0", + "fq": "^0.3.0", + "pg": "^4.1.1", + "amqp": "^0.2.0" + } +} diff --git a/src/js/test.js b/src/js/test.js new file mode 100644 index 000000000..3243672c4 --- /dev/null +++ b/src/js/test.js @@ -0,0 +1,63 @@ +var sys = require('sys'), + crypto = require('crypto'), + ls = require('./index'), + cafile = 'dummy-ca.crt', + keyfile = 'dummy.key', + certfile = 'dummy.crt', + host = '127.0.0.1', + cn = null, + proxy_port = null, + period = 1000, + id = '9beeffef-fee8-4885-987a-faa10f16e724', + debug = false; + +function help() { + console.log(process.argv[0] + "\n" + + " [-l ] : proxy port\n" + + " [-d] : debug\n" + + " [(-h|-host) host] : noit\n" + + " [(-c|-cn) cn] : noit cn\n" + + " [(-p|-period) period] : period in ms\n" + + " [(-i|-id) uuid] : check uuid\n" + + " [-cafile filename] : CA\n" + + " [-keyfile filename] : client key\n" + + " [-certfile filename] : client cert\n"); +} +for(var i=2; i