Skip to content
This repository
Browse code

Add AWS.MetadataService to query EC2 instance metadata

  • Loading branch information...
commit bdc6fbbd769757457d3a20f11b4060a8a7a97991 1 parent 380009a
Loren Segal authored March 14, 2013
65  lib/metadata_service.js
... ...
@@ -0,0 +1,65 @@
  1
+/**
  2
+ * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3
+ *
  4
+ * Licensed under the Apache License, Version 2.0 (the "License"). You
  5
+ * may not use this file except in compliance with the License. A copy of
  6
+ * the License is located at
  7
+ *
  8
+ *     http://aws.amazon.com/apache2.0/
  9
+ *
  10
+ * or in the "license" file accompanying this file. This file is
  11
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  12
+ * ANY KIND, either express or implied. See the License for the specific
  13
+ * language governing permissions and limitations under the License.
  14
+ */
  15
+
  16
+var AWS = require('./core');
  17
+require('./http');
  18
+var inherit = AWS.util.inherit;
  19
+
  20
+AWS.MetadataService = inherit({
  21
+  host: '169.254.169.254',
  22
+  httpOptions: { timeout: 1000 },
  23
+
  24
+  constructor: function MetadataService(options) {
  25
+    AWS.util.update(this, options);
  26
+  },
  27
+
  28
+  request: function request(path, callback) {
  29
+    path = path || '/';
  30
+
  31
+    var data = '';
  32
+    var http = AWS.HttpClient.getInstance();
  33
+    var httpRequest = new AWS.HttpRequest('http://' + this.host + path);
  34
+    httpRequest.method = 'GET';
  35
+
  36
+    http.handleRequest(httpRequest, this.httpOptions, function(httpResponse) {
  37
+      httpResponse.on('data', function(chunk) { data += chunk.toString(); });
  38
+      httpResponse.on('end', function() { callback(null, data); });
  39
+    }, callback);
  40
+  },
  41
+
  42
+  loadCredentials: function loadCredentials(callback) {
  43
+    var self = this;
  44
+    var basePath = '/latest/meta-data/iam/security-credentials/';
  45
+    self.request(basePath, function (err, roleName) {
  46
+      if (err) callback(err);
  47
+      else {
  48
+        roleName = roleName.split('\n')[0]; // grab first (and only) role
  49
+        self.request(basePath + roleName, function (credErr, credData) {
  50
+          if (credErr) callback(credErr);
  51
+          else {
  52
+            try {
  53
+              var credentials = JSON.parse(credData);
  54
+              callback(null, credentials);
  55
+            } catch (parseError) {
  56
+              callback(parseError);
  57
+            }
  58
+          }
  59
+        });
  60
+      }
  61
+    });
  62
+  }
  63
+});
  64
+
  65
+module.exports = AWS.MetadataService;
66  test/metadata_service.spec.coffee
... ...
@@ -0,0 +1,66 @@
  1
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  2
+#
  3
+# Licensed under the Apache License, Version 2.0 (the "License"). You
  4
+# may not use this file except in compliance with the License. A copy of
  5
+# the License is located at
  6
+#
  7
+#     http://aws.amazon.com/apache2.0/
  8
+#
  9
+# or in the "license" file accompanying this file. This file is
  10
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  11
+# ANY KIND, either express or implied. See the License for the specific
  12
+# language governing permissions and limitations under the License.
  13
+
  14
+helpers = require('./helpers')
  15
+url = require('url')
  16
+http = require('http')
  17
+AWS = helpers.AWS
  18
+
  19
+describe 'AWS.MetadataService', ->
  20
+  describe 'loadCredentials', ->
  21
+    [server, port, service] = [null, 1024 + parseInt(Math.random() * 100), null]
  22
+
  23
+    beforeEach ->
  24
+      service = new AWS.MetadataService(host: '127.0.0.1:' + port)
  25
+      server = http.createServer (req, res) ->
  26
+        re = new RegExp('^/latest/meta-data/iam/security-credentials/(.*)$')
  27
+        match = url.parse(req.url).pathname.match(re)
  28
+        if match
  29
+          res.writeHead(200, 'Content-Type': 'text/plain')
  30
+          if match[1] == ''
  31
+            res.write('TestingRole\n')
  32
+            res.write('TestingRole2\n')
  33
+          else
  34
+            data = '{"Code":"Success","AccessKeyId":"KEY","SecretAccessKey":"SECRET","Token":"TOKEN"}'
  35
+            res.write(data)
  36
+        else
  37
+          res.writeHead(404, {})
  38
+        res.end()
  39
+
  40
+      server.listen(port)
  41
+
  42
+    afterEach -> server.close() if server
  43
+
  44
+    it 'should load credentials from metadata service', ->
  45
+      [err, data] = [null, null]
  46
+      runs ->
  47
+        service.loadCredentials (e, d) -> [err, data] = [e, d]
  48
+      waitsFor -> err || data
  49
+      runs ->
  50
+        expect(err).toBe(null)
  51
+        expect(data.Code).toEqual('Success')
  52
+        expect(data.AccessKeyId).toEqual('KEY')
  53
+        expect(data.SecretAccessKey).toEqual('SECRET')
  54
+        expect(data.Token).toEqual('TOKEN')
  55
+
  56
+    it 'should fail if server is not up', ->
  57
+      server.close(); server = null
  58
+      service = new AWS.MetadataService()
  59
+      service.httpOptions.timeout = 10
  60
+      [err, data] = [null, null]
  61
+      runs ->
  62
+        service.loadCredentials (e, d) -> [err, data] = [e, d]
  63
+      waitsFor -> err || data
  64
+      runs ->
  65
+        expect(err instanceof Error).toBe(true)
  66
+        expect(data).toEqual(null)

0 notes on commit bdc6fbb

Please sign in to comment.
Something went wrong with that request. Please try again.