Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Merge e68d9e4 into 64bfc81
Browse files Browse the repository at this point in the history
  • Loading branch information
aung-r7 committed May 15, 2019
2 parents 64bfc81 + e68d9e4 commit c3fcf1b
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 41 deletions.
4 changes: 4 additions & 0 deletions src/lib/transformers/tokend-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ class TokendClient extends Source.Polling(TokendParser) {
'Content-Length': Buffer.byteLength(content)
}
}, (res) => {
if (res.statusCode !== 200) {
callback(new Error("ERROR: Unable to decrypt secret"), null)
}

res.setEncoding('utf8');
res.on('data', (chunk) => {
secret += chunk;
Expand Down
18 changes: 14 additions & 4 deletions src/lib/transformers/tokend.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ class TokendTransformer {
const opts = options || {};

this._client = new TokendClient(opts);
this._previousProperties = {};
this._cache = {};

this._interval = opts.cacheTTL || DEFAULT_CACHE_TTL;

setImmediate(() => {
this._previousProperties = {};
this._cache = {};

this._expireCache();
Expand All @@ -73,6 +75,10 @@ class TokendTransformer {
const i = Math.random() * ((this._interval + 60000) - this._interval) + this._interval;

setTimeout(() => {
if (Object.keys(this._cache).length !== 0) {
this._previousProperties = this._cache;
}

this._cache = {};
this._expireCache();
}, i);
Expand Down Expand Up @@ -109,9 +115,9 @@ class TokendTransformer {
}

let resolver = null,
payload = {},
method = '',
source = 'Vault';
payload = {},
method = '',
source = 'Vault';

switch (info.get('type')) {
case 'generic':
Expand Down Expand Up @@ -175,9 +181,13 @@ class TokendTransformer {

return Promise.resolve(Immutable.Map().setIn(keyPath, data.plaintext));
}).catch((err) => {
Log.log('WARN', err);
this._client.clearCacheAtKey(method, requestId);

if (this._previousProperties.hasOwnProperty(signature)) {
return Promise.resolve(Immutable.Map().setIn(keyPath, this._previousProperties[signature].plaintext));
}

Log.log('WARN', err);
return Promise.resolve(Immutable.Map().setIn(keyPath, null));
});
});
Expand Down
142 changes: 105 additions & 37 deletions test/metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,58 @@ describe('Metadata source plugin', function _() {
const metadataPaths = require('./data/metadata-paths.json');
const metadataValues = require('./data/metadata-values.json');

it('traverses metadata paths', function __(done) {
it.only('periodically fetches metadata from the EC2 metadata API', function __(done) {
this.timeout(2500);

// Stub the AWS.MetadataService request method
AWS.mock('MetadataService', 'request', (path, callback) => {
callback(null, metadataPaths[path]);
});
AWS.mock('AutoScaling', 'describeAutoScalingInstances', (params, callback) => {
callback(null, { AutoScalingInstances: [] });
});

const source = new Metadata({
interval: 100
});

source.once('update', () => {
// Currently used in our Index object.
// console.log('first');
expect(source.properties.account).to.be.a('string');
expect(source.properties.region).to.be.a('string');
expect(source.properties['vpc-id']).to.be.a('string');
expect(source.properties['iam-role']).to.eq('fake-fake');
expect(source.properties['instance-id']).to.be.a('string');

expect(source.properties.identity).to.be.an('object');
expect(source.properties.credentials).to.be.an('object');
expect(source.properties.interface).to.be.an('object');

// source.once('noupdate', () => {
// console.log('in here?');
// expect(source.state).to.equal(Metadata.RUNNING);
// source.shutdown();

// AWS.restore();
// done();
// });
// done();
});

source.once('noupdate', () => {
// console.log('in here?');
expect(source.state).to.equal(Metadata.RUNNING);
source.shutdown();

AWS.restore();
done();
});

source.initialize();
});

it.only('traverses metadata paths', function __(done) {
Util.traverse('latest', Parser.paths,
(path, cb) => cb(null, metadataPaths[path]),
(err, data) => {
Expand All @@ -28,7 +79,7 @@ describe('Metadata source plugin', function _() {
);
});

it('parses traversed values into a useful object', function __() {
it.only('parses traversed values into a useful object', function __() {
const parser = new Parser();

parser.update(metadataValues);
Expand All @@ -45,7 +96,7 @@ describe('Metadata source plugin', function _() {
expect(parser.properties.interface).to.be.an('object');
});

it('doesn\'t display values that are undefined', function() {
it.only('doesn\'t display values that are undefined', function () {
const parser = new Parser();
const deletedMetadataValues = Object.assign({}, metadataValues);

Expand All @@ -59,7 +110,7 @@ describe('Metadata source plugin', function _() {
expect(parser.properties).to.not.have.property('region');
});

it('handles errors from the AWS SDK gracefully by not exposing the property', function(done) {
it.only('handles errors from the AWS SDK gracefully by not exposing the property', function (done) {
AWS.mock('MetadataService', 'request', (path, callback) => {
callback(new Error('some error from the AWS SDK'), null);
});
Expand All @@ -78,15 +129,18 @@ describe('Metadata source plugin', function _() {
source.initialize();
});

it('periodically fetches metadata from the EC2 metadata API', function __(done) {
it.only('retrieves ASG info for the instance', function (done) {
this.timeout(2500);

// Stub the AWS.MetadataService request method
AWS.mock('MetadataService', 'request', (path, callback) => {
callback(null, metadataPaths[path]);
});
AWS.mock('AutoScaling', 'describeAutoScalingInstances', (params, callback) => {
callback(null, {AutoScalingInstances: []});
callback(null, {
AutoScalingInstances: [{
AutoScalingGroupName: 'my-cool-auto-scaling-group'
}]
});
});

const source = new Metadata({
Expand All @@ -95,48 +149,32 @@ describe('Metadata source plugin', function _() {

source.once('update', () => {
// Currently used in our Index object.
expect(source.properties.account).to.be.a('string');
expect(source.properties.region).to.be.a('string');
expect(source.properties['vpc-id']).to.be.a('string');
expect(source.properties['iam-role']).to.eq('fake-fake');
expect(source.properties['instance-id']).to.be.a('string');

expect(source.properties.identity).to.be.an('object');
expect(source.properties.credentials).to.be.an('object');
expect(source.properties.interface).to.be.an('object');

source.once('noupdate', () => {
expect(source.state).to.equal(Metadata.RUNNING);
source.shutdown();
expect(source.properties['auto-scaling-group']).to.be.a('string');
expect(source.properties['auto-scaling-group']).to.equal('my-cool-auto-scaling-group');

AWS.restore();
done();
});
AWS.restore();
done();
});

source.initialize();
});

it('retrieves ASG info for the instance', function(done) {
it.only('handles ASG errors from the AWS SDK by not surfacing the auto-scaling-group property', function (done) {
this.timeout(2500);

AWS.mock('MetadataService', 'request', (path, callback) => {
callback(null, metadataPaths[path]);
});
AWS.mock('AutoScaling', 'describeAutoScalingInstances', (params, callback) => {
callback(null, {AutoScalingInstances: [{
AutoScalingGroupName: 'my-cool-auto-scaling-group'
}]});
callback(new Error('some error from the AWS SDK'), null);
});

const source = new Metadata({
interval: 100
});

source.once('update', () => {
// Currently used in our Index object.
expect(source.properties['auto-scaling-group']).to.be.a('string');
expect(source.properties['auto-scaling-group']).to.equal('my-cool-auto-scaling-group');
expect(source.properties['auto-scaling-group']).to.be.undefined;

AWS.restore();
done();
Expand All @@ -145,17 +183,19 @@ describe('Metadata source plugin', function _() {
source.initialize();
});

it('only retrieves ASG data once', function(done) {
it.only('only retrieves ASG data once', function (done) {
const asgSpy = sinon.spy();

AWS.mock('MetadataService', 'request', (path, callback) => {
callback(null, metadataPaths[path]);
});
AWS.mock('AutoScaling', 'describeAutoScalingInstances', (params, callback) => {
asgSpy();
callback(null, {AutoScalingInstances: [{
AutoScalingGroupName: 'my-cool-auto-scaling-group'
}]});
callback(null, {
AutoScalingInstances: [{
AutoScalingGroupName: 'my-cool-auto-scaling-group'
}]
});
});

const source = new Metadata({
Expand All @@ -168,29 +208,57 @@ describe('Metadata source plugin', function _() {

source.once('noupdate', () => {
expect(asgSpy.calledOnce).to.be.true;
source.shutdown();
AWS.restore();
done();
});

source.initialize();
});

it('handles ASG errors from the AWS SDK by not surfacing the auto-scaling-group property', function(done) {
it.only('periodically fetches metadata from the EC2 metadata API', function __(done) {
this.timeout(2500);

// Stub the AWS.MetadataService request method
AWS.mock('MetadataService', 'request', (path, callback) => {
callback(null, metadataPaths[path]);
});
AWS.mock('AutoScaling', 'describeAutoScalingInstances', (params, callback) => {
callback(new Error('some error from the AWS SDK'), null);
callback(null, { AutoScalingInstances: [] });
});

const source = new Metadata({
interval: 100
});

source.once('update', () => {
expect(source.properties['auto-scaling-group']).to.be.undefined;
// Currently used in our Index object.
// console.log('first');
expect(source.properties.account).to.be.a('string');
expect(source.properties.region).to.be.a('string');
expect(source.properties['vpc-id']).to.be.a('string');
expect(source.properties['iam-role']).to.eq('fake-fake');
expect(source.properties['instance-id']).to.be.a('string');

expect(source.properties.identity).to.be.an('object');
expect(source.properties.credentials).to.be.an('object');
expect(source.properties.interface).to.be.an('object');

// source.once('noupdate', () => {
// console.log('in here?');
// expect(source.state).to.equal(Metadata.RUNNING);
// source.shutdown();

// AWS.restore();
// done();
// });
// done();
});

source.once('noupdate', () => {
// console.log('in here?');
expect(source.state).to.equal(Metadata.RUNNING);
source.shutdown();

AWS.restore();
done();
Expand Down

0 comments on commit c3fcf1b

Please sign in to comment.