Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Add AWS.MetadataService to query EC2 instance metadata

  • Loading branch information...
commit bdc6fbbd769757457d3a20f11b4060a8a7a97991 1 parent 380009a
@lsegal lsegal authored
Showing with 131 additions and 0 deletions.
  1. +65 −0 lib/metadata_service.js
  2. +66 −0 test/metadata_service.spec.coffee
View
65 lib/metadata_service.js
@@ -0,0 +1,65 @@
+/**
+ * Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"). You
+ * may not use this file except in compliance with the License. A copy of
+ * the License is located at
+ *
+ * http://aws.amazon.com/apache2.0/
+ *
+ * or in the "license" file accompanying this file. This file is
+ * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+ * ANY KIND, either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ */
+
+var AWS = require('./core');
+require('./http');
+var inherit = AWS.util.inherit;
+
+AWS.MetadataService = inherit({
+ host: '169.254.169.254',
+ httpOptions: { timeout: 1000 },
+
+ constructor: function MetadataService(options) {
+ AWS.util.update(this, options);
+ },
+
+ request: function request(path, callback) {
+ path = path || '/';
+
+ var data = '';
+ var http = AWS.HttpClient.getInstance();
+ var httpRequest = new AWS.HttpRequest('http://' + this.host + path);
+ httpRequest.method = 'GET';
+
+ http.handleRequest(httpRequest, this.httpOptions, function(httpResponse) {
+ httpResponse.on('data', function(chunk) { data += chunk.toString(); });
+ httpResponse.on('end', function() { callback(null, data); });
+ }, callback);
+ },
+
+ loadCredentials: function loadCredentials(callback) {
+ var self = this;
+ var basePath = '/latest/meta-data/iam/security-credentials/';
+ self.request(basePath, function (err, roleName) {
+ if (err) callback(err);
+ else {
+ roleName = roleName.split('\n')[0]; // grab first (and only) role
+ self.request(basePath + roleName, function (credErr, credData) {
+ if (credErr) callback(credErr);
+ else {
+ try {
+ var credentials = JSON.parse(credData);
+ callback(null, credentials);
+ } catch (parseError) {
+ callback(parseError);
+ }
+ }
+ });
+ }
+ });
+ }
+});
+
+module.exports = AWS.MetadataService;
View
66 test/metadata_service.spec.coffee
@@ -0,0 +1,66 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+# http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+
+helpers = require('./helpers')
+url = require('url')
+http = require('http')
+AWS = helpers.AWS
+
+describe 'AWS.MetadataService', ->
+ describe 'loadCredentials', ->
+ [server, port, service] = [null, 1024 + parseInt(Math.random() * 100), null]
+
+ beforeEach ->
+ service = new AWS.MetadataService(host: '127.0.0.1:' + port)
+ server = http.createServer (req, res) ->
+ re = new RegExp('^/latest/meta-data/iam/security-credentials/(.*)$')
+ match = url.parse(req.url).pathname.match(re)
+ if match
+ res.writeHead(200, 'Content-Type': 'text/plain')
+ if match[1] == ''
+ res.write('TestingRole\n')
+ res.write('TestingRole2\n')
+ else
+ data = '{"Code":"Success","AccessKeyId":"KEY","SecretAccessKey":"SECRET","Token":"TOKEN"}'
+ res.write(data)
+ else
+ res.writeHead(404, {})
+ res.end()
+
+ server.listen(port)
+
+ afterEach -> server.close() if server
+
+ it 'should load credentials from metadata service', ->
+ [err, data] = [null, null]
+ runs ->
+ service.loadCredentials (e, d) -> [err, data] = [e, d]
+ waitsFor -> err || data
+ runs ->
+ expect(err).toBe(null)
+ expect(data.Code).toEqual('Success')
+ expect(data.AccessKeyId).toEqual('KEY')
+ expect(data.SecretAccessKey).toEqual('SECRET')
+ expect(data.Token).toEqual('TOKEN')
+
+ it 'should fail if server is not up', ->
+ server.close(); server = null
+ service = new AWS.MetadataService()
+ service.httpOptions.timeout = 10
+ [err, data] = [null, null]
+ runs ->
+ service.loadCredentials (e, d) -> [err, data] = [e, d]
+ waitsFor -> err || data
+ runs ->
+ expect(err instanceof Error).toBe(true)
+ expect(data).toEqual(null)
Please sign in to comment.
Something went wrong with that request. Please try again.