all files / src/ AwsMetadata.js

100% Statements 54/54
96.67% Branches 29/30
100% Functions 23/23
100% Lines 38/38
1 statement, 1 branch Ignored     
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87             15× 15× 15×                                                     33× 33×           30×     30×   30×                    
import request from 'request';
import async from 'async';
import Logger from './Logger';
 
/*
  Utility class for pulling AWS metadata that Eureka requires when
  registering as an Amazon instance (datacenter).
*/
export default class AwsMetadata {
 
  constructor(config = {}) {
    this.logger = config.logger || new Logger();
    this.host = config.host || '169.254.169.254';
  }
 
  fetchMetadata(resultsCallback) {
    async.parallel({
      'ami-id': callback => {
        this.lookupMetadataKey('ami-id', callback);
      },
      'instance-id': callback => {
        this.lookupMetadataKey('instance-id', callback);
      },
      'instance-type': callback => {
        this.lookupMetadataKey('instance-type', callback);
      },
      'local-ipv4': callback => {
        this.lookupMetadataKey('local-ipv4', callback);
      },
      'local-hostname': callback => {
        this.lookupMetadataKey('local-hostname', callback);
      },
      'availability-zone': callback => {
        this.lookupMetadataKey('placement/availability-zone', callback);
      },
      'public-hostname': callback => {
        this.lookupMetadataKey('public-hostname', callback);
      },
      'public-ipv4': callback => {
        this.lookupMetadataKey('public-ipv4', callback);
      },
      mac: callback => {
        this.lookupMetadataKey('mac', callback);
      },
      accountId: callback => {
        // the accountId is in the identity document.
        this.lookupInstanceIdentity((error, identity) => {
          callback(null, identity ? identity.accountId : null);
        });
      },
    }, (error, results) => {
      // we need the mac before we can lookup the vpcId...
      this.lookupMetadataKey(`network/interfaces/macs/${results.mac}/vpc-id`, (err, vpcId) => {
        results['vpc-id'] = vpcId;
        this.logger.debug('Found Instance AWS Metadata', results);
        const filteredResults = Object.keys(results).reduce((filtered, prop) => {
          if (results[prop]) filtered[prop] = results[prop];
          return filtered;
        }, {});
        resultsCallback(filteredResults);
      });
    });
  }
 
  lookupMetadataKey(key, callback) {
    request.get({
      url: `http://${this.host}/latest/meta-data/${key}`,
    }, (error, response, body) => {
      if (error) {
        this.logger.error('Error requesting metadata key', error);
      }
      callback(null, (error || response.statusCode !== 200) ? null : body);
    });
  }
 
  lookupInstanceIdentity(callback) {
    request.get({
      url: `http://${this.host}/latest/dynamic/instance-identity/document`,
    }, (error, response, body) => {
      if (error) {
        this.logger.error('Error requesting instance identity document', error);
      }
      callback(null, (error || response.statusCode !== 200) ? null : JSON.parse(body));
    });
  }
}