|
/* |
|
|
|
Author:: Rad Gruchalski (<[email protected]>) |
|
License:: The MIT License (MIT) |
|
https://gist.github.com/radekg/5662007 |
|
|
|
The MIT License (MIT) |
|
|
|
Copyright (c) 2013 Rad Gruchalski |
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
of this software and associated documentation files (the "Software"), to deal |
|
in the Software without restriction, including without limitation the rights |
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
copies of the Software, and to permit persons to whom the Software is |
|
furnished to do so, subject to the following conditions: |
|
|
|
The above copyright notice and this permission notice shall be included in |
|
all copies or substantial portions of the Software. |
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
|
THE SOFTWARE. |
|
|
|
|
|
This module depends on log4js and aws-sdk. |
|
To use: |
|
|
|
var logger = log4js.getLogger("your-logger-name"); |
|
var credentials = new Credentials(AWS, logger); |
|
credentials.on("iamReloaded", function() { |
|
AWS.config.update({ |
|
endpoint: (config ? config.AWS.endpoint : "s3-eu-west-1.amazonaws.com") |
|
, region: (config ? config.AWS.region : "eu-west-1") |
|
, accessKeyId: credentials.accessKeyId |
|
, secretAccessKey: credentials.secretAccessKey |
|
, sessionToken: credentials.sessionToken |
|
}); |
|
s3 = new AWS.S3(); |
|
}); |
|
credentials.fetch(function() { |
|
logger.info("IAM credentials loaded."); |
|
logger.info([ credentials.role, credentials.accessKeyId, credentials.secretAccessKey, credentials.sessionToken ]); |
|
credentials.emit("iamReloaded"); |
|
|
|
startYourAppHere(); |
|
}); |
|
*/ |
|
|
|
var spawn = require("child_process").spawn |
|
util = require("util"); |
|
|
|
var Credentials = function(AWS, logger) { |
|
this.accessKeyId = ""; |
|
this.secretAccessKey = ""; |
|
this.sessionToken = ""; |
|
this.expiration = null; |
|
this.role = null; |
|
this._$logger = logger; |
|
this._$aws = AWS; |
|
this._$fetcher = null; |
|
}; |
|
util.inherits(Credentials, process.EventEmitter); |
|
|
|
Credentials.prototype.getSecurityRole = function(callback) { |
|
var self = this; |
|
var get = spawn( "GET", ["http://169.254.169.254/latest/meta-data/iam/security-credentials"] ); |
|
var fullData = ""; |
|
var fullError = ""; |
|
get.stdout.on("data", function(data) { |
|
fullData += data+""; |
|
}); |
|
get.stderr.on("data", function(data) { |
|
fullError += data+""; |
|
}); |
|
get.on("exit", function(code) { |
|
self.role = (fullData+"").toLowerCase(); |
|
callback( code, fullError, fullData ); |
|
}); |
|
}; |
|
|
|
Credentials.prototype.getTempSecurityCredentials = function(role, callback) { |
|
var get = spawn( "GET", ["http://169.254.169.254/latest/meta-data/iam/security-credentials/" + role] ); |
|
var fullData = ""; |
|
var fullError = ""; |
|
get.stdout.on("data", function(data) { |
|
fullData += data+""; |
|
}); |
|
get.stderr.on("data", function(data) { |
|
fullError += data+""; |
|
}); |
|
get.on("exit", function(code) { |
|
callback( code, fullError, fullData ); |
|
}); |
|
}; |
|
|
|
Credentials.prototype.fetch = function(callback) { |
|
var self = this; |
|
clearInterval( this._$fetcher ); |
|
this.getSecurityRole( function( code, error, data ) { |
|
self.getTempSecurityCredentials( data, function(code, error, data ) { |
|
|
|
data = JSON.parse(data); |
|
|
|
self.accessKeyId = data.AccessKeyId; |
|
self.secretAccessKey = data.SecretAccessKey; |
|
self.sessionToken = data.Token; |
|
self.expiration = self.toDate( data.Expiration ); |
|
self.emit("ready", self); |
|
|
|
self._$fetcher = setInterval(function() { |
|
if ( self.expiration.getTime() < Date.now() ) { |
|
self._$logger.trace("Refreshing IAM credentials."); |
|
self.fetch(function() { |
|
self._$logger.trace("IAM credentials refreshed."); |
|
self.emit("iamReloaded"); |
|
}); |
|
|
|
} |
|
}, 1000); |
|
|
|
callback(); |
|
|
|
}); |
|
}); |
|
}; |
|
|
|
Credentials.prototype.toDate = function(str) { |
|
var unpad = function(d) { |
|
if ( d.indexOf("0") == 0 ) { |
|
return parseInt(d.substr(1,1)); |
|
} |
|
return parseInt(d); |
|
}; |
|
var parts = str.split("T"); |
|
var dateParts = parts[0].split("-"); |
|
var timeParts = parts[1].split("Z")[0].split(":"); |
|
return new Date( parseInt(dateParts[0]), unpad(dateParts[1])-1, unpad(dateParts[2]), unpad(timeParts[0]), unpad(timeParts[1]), unpad(timeParts[2]) ); |
|
}; |
|
|
|
module.exports = Credentials; |