forked from matschaffer/redis_twemproxy_agent
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial commit with code from https://gist.github.com/eveiga/5039007 …
…wrapped in an npm module
- Loading branch information
0 parents
commit 8f9eb18
Showing
7 changed files
with
178 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/node_modules | ||
/*.tgz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Redis-Twemproxy Agent | ||
|
||
This originally started as a [gist](https://gist.github.com/eveiga/5039007) posted on [a twemproxy ticket about doing HA redis](https://github.com/twitter/twemproxy/issues/67). | ||
|
||
Edgar was nice enough to share what he had so far and now I'm trying to take it a bit further in hopes of making a generalized package. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/usr/bin/env node | ||
|
||
var path = require('path'); | ||
require(path.join(__dirname,'../lib/cli.js')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
var fs = require('fs'), | ||
exec = require('child_process').exec, | ||
path = require('path'), | ||
os = require('os'); | ||
|
||
var Sentinel = require("node-sentinel"), | ||
_ = require("underscore"), | ||
async = require("async"), | ||
nodemailer = require("nodemailer"); | ||
|
||
function Agent(config){ | ||
if(!_.isObject(config)){ | ||
return console.error("Bad config"); | ||
} | ||
|
||
this.nutcracker_config_file = config.nutcracker_config_file; | ||
this.redis_sentinel_ip = config.redis_sentinel_ip; | ||
this.redis_sentinel_port = config.redis_sentinel_port; | ||
this.log = ""; | ||
} | ||
|
||
Agent.prototype.restart_nutcracker = function(callback){ | ||
var self = this; | ||
var child = exec( | ||
"/etc/init.d/nutcracker restart", | ||
function(error, stdout, stderr) { | ||
self.log += "<h2>Nutcracker restarted with outuput:</h2>"; | ||
self.log += "<div><pre>"+stdout+"</pre></div>"; | ||
|
||
if (error !== null) { | ||
self.log += "<h2>Nutcracker failed restarting with error:</h2>"; | ||
self.log += "<div><pre>"+error+"</pre></div>"; | ||
} | ||
return callback(); | ||
} | ||
); | ||
}; | ||
|
||
Agent.prototype.update_nutcracker_config = function(data, callback){ | ||
var old_content = fs.readFileSync(this.nutcracker_config_file, 'utf8'); | ||
|
||
var new_content = old_content.replace( | ||
data.details["old-ip"]+":"+data.details["old-port"], | ||
data.details["new-ip"]+":"+data.details["new-port"] | ||
); | ||
|
||
fs.writeFileSync(this.nutcracker_config_file, new_content, 'utf8'); | ||
|
||
this.log += "<h2>Nutcracker config updated with new content:</h2>"; | ||
this.log += "<div><pre>"+new_content+"</pre></div>"; | ||
|
||
return callback(); | ||
}; | ||
|
||
Agent.prototype.send_mail = function() { | ||
var self = this; | ||
var transport = nodemailer.createTransport("Sendmail"); | ||
|
||
var mailOptions = { | ||
from: "from@mail.com", | ||
to: "to@mail.com", | ||
subject: "Warning: Nutcracker restarted forced on "+os.hostname(), | ||
generateTextFromHTML: true, | ||
html: "<h1>Nutcracker was restarted due to master switch in redis configuration.</h1>" + this.log | ||
}; | ||
|
||
transport.sendMail(mailOptions, function(error, responseStatus){ | ||
self.log = ""; | ||
if(error) { | ||
return console.error(error); | ||
} | ||
|
||
return console.info( | ||
responseStatus.message+"\n"+responseStatus.messageId | ||
); | ||
}); | ||
}; | ||
|
||
Agent.prototype.switch_master_handler = function(){ | ||
var self = this; | ||
return function(data) { | ||
async.series([ | ||
function(callback) { | ||
self.update_nutcracker_config(data, callback); | ||
}, | ||
function(callback) { | ||
self.restart_nutcracker(callback); | ||
} | ||
], | ||
function(){ | ||
return self.send_mail(); | ||
}); | ||
}; | ||
}; | ||
|
||
Agent.prototype.start_sentinel = function(){ | ||
this.sentinel = new Sentinel( | ||
this.redis_sentinel_ip, this.redis_sentinel_port | ||
); | ||
|
||
this.sentinel.on("switch-master", this.switch_master_handler()); | ||
}; | ||
|
||
Agent.prototype.check_nutcracker_config = function(cb){ | ||
fs.appendFile(this.nutcracker_config_file, "", cb); | ||
}; | ||
|
||
Agent.prototype.bootstrap = function(){ | ||
var self = this; | ||
|
||
this.check_nutcracker_config( | ||
function(error){ | ||
if(error) { | ||
return console.error("Nutcracker config file: "+error); | ||
} | ||
|
||
return self.start_sentinel(); | ||
} | ||
); | ||
}; | ||
|
||
module.exports = Agent; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
var util = require('util'); | ||
|
||
util.puts("The CLI will go here"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
{ | ||
"name": "redis_twemproxy_agent", | ||
"version": "0.0.1", | ||
"description": "Redis agent for nutcracker update", | ||
"preferGlobal": true, | ||
"bin": "bin/redis_twemproxy_agent", | ||
"main": "lib/agent.js", | ||
"scripts": { | ||
"test": "jshint lib spec && jasmine-node spec" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/matschaffer/redis_twemproxy_agent.git" | ||
}, | ||
"keywords": [ | ||
"redis", | ||
"twemproxy", | ||
"ha" | ||
], | ||
"author": "Edgar Veiga <edgarmveiga@gmail.com>", | ||
"contributors": [ | ||
"Mat Schaffer <mat@schaffer.me>" | ||
], | ||
"license": "BSD", | ||
"dependencies": { | ||
"node-sentinel": "0.0.4", | ||
"underscore": "~1.4.4", | ||
"async": "~0.2.5", | ||
"nodemailer": "~0.3.42" | ||
}, | ||
"devDependencies": { | ||
"jshint": "~1.0.0", | ||
"jasmine-node": "~1.3.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
var Agent = require("../lib/agent.js"); | ||
|
||
describe("Redis Twemproxy Agent", function() { | ||
it("subscribes to master switch notifications"); | ||
it("swaps old master information with new master information"); | ||
it("restarts twemproxy"); | ||
}); |