Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/modules/resty.aws.utils.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ <h2><a href="#Functions">Functions</a></h2>
<td class="name" nowrap><a href="#Utils.getIDMSMetadata">Utils.getIDMSMetadata (subpath, version)</a></td>
<td class="summary">Fetches IDMS Metadata (EC2 and EKS).</td>
</tr>
<tr>
<td class="name" nowrap><a href="#Utils.getInstanceSignature">Utils.getInstanceSignature ()</a></td>
<td class="summary">Fetches the instance identity document and signature from IDMS.</td>
</tr>
</table>

<br/>
Expand Down Expand Up @@ -190,6 +194,22 @@ <h3>Returns:</h3>


</dd>

<!-- generate doc for Utils.getInstanceSignature -->
<dt>
<a name = "Utils.getInstanceSignature"></a>
<strong>Utils.getInstanceSignature ()</strong>
</dt>
<dd>
Fetches the instance identity document and signature from IDMS.
Will make a call to the AWS identity endpoint and hence might timeout if ran on anything
else than an EC2-instance.
<h3>Returns:</h3>
<ol>
body &amp; content-type (if json, the body will be decoded to a Lua table), or nil+err
</ol>
</dd>

</dl>


Expand Down
58 changes: 58 additions & 0 deletions spec/01-generic/04-utils_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
local utils = require "resty.aws.utils"

describe("Utils:getInstanceSignature", function()
local mock_token = "mock-imds-token-12345"
local mock_signature = "-----BEGIN PKCS7-----\nMIAGCSqGSIb3DQEHAqCAMIACAQExCzAJ\n-----END PKCS7-----\n"
local expected_signature = "-----BEGIN PKCS7-----MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJ-----END PKCS7-----"

local http = {
new = function()
return {
connect = function() return true end,
set_timeouts = function() return true end,
close = function() end,
request_uri = function(self, uri, opts)
if string.find(uri, "/latest/api/token") then
ngx.log(ngx.ERR, "Returning mock IMDSv2 token")
return {
status = 200,
headers = {
["Content-Type"] = "application/xml",
},
body = mock_token
}
elseif string.find(uri, "/rsa2048") then
return {
status = 200,
headers = {
["Content-Type"] = "application/xml",
},
body = mock_signature
}
end
end,
}
end
}

setup(function()
package.loaded["resty.luasocket.http"] = http
end)

teardown(function()
package.loaded["resty.luasocket.http"] = nil
end)

before_each(function()
package.loaded["resty.luasocket.http"] = http
package.loaded["resty.aws.utils"] = nil
utils = require "resty.aws.utils"
end)

it("fetches instance signature successfully with IMDSv2", function()
local signature, err = utils.getInstanceSignature()

assert.is_nil(err)
assert.equals(expected_signature, signature)
end)
end)
20 changes: 20 additions & 0 deletions src/resty/aws/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,26 @@ do -- getCurrentRegion

return detected_region, detected_error
end


--- Retrieves the RSA2048 signature from EC2 instance metadata.
-- @return signature string, or nil+err
function Utils.getInstanceSignature()
local headers = { ["X-aws-ec2-metadata-token-ttl-seconds"] = "21600" }
local token, err = make_request(IDMS_URI .. "/latest/api/token", "PUT", headers)
if not token then
return nil, "failed getting IDMSToken: " .. tostring(err)
end

headers = { ["X-aws-ec2-metadata-token"] = token }
local signature, err = make_request(IDMS_URI .. "/latest/dynamic/instance-identity/rsa2048", "GET", headers)
if not signature then
return nil, "failed getting instance signature: " .. tostring(err)
end

signature = signature:gsub("\n", "")
return signature
end
end

return Utils
Loading