diff --git a/DESCRIPTION b/DESCRIPTION index 5f17025..d76be95 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,13 +1,14 @@ Package: aws.ec2metadata Type: Package Title: Get EC2 Instance Metadata -Version: 0.2.0 +Version: 0.2.1 Date: 2019-07-15 Authors@R: c(person("Thomas J.", "Leeper", role = c("aut"), email = "thosjleeper@gmail.com", comment = c(ORCID = "0000-0003-4097-6326")), person("Jonathan", "Stott", role = c("cre", "aut"), - email = "jonathan.stott@magairports.com") + email = "jonathan.stott@magairports.com"), + person("Michael","Condouris", role=c("ctb"), email="condour@gmail.com") ) Description: Retrieve Amazon EC2 instance metadata from within the running instance. License: GPL (>= 2) @@ -16,4 +17,4 @@ BugReports: https://github.com/cloudyr/aws.ec2metadata/issues Imports: curl, jsonlite -RoxygenNote: 6.1.1 +RoxygenNote: 7.2.0 diff --git a/NEWS.md b/NEWS.md index 182508d..7a939f8 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# aws.ec2metadata 0.2.1 + +* add IMDSv2 support (#10) + # aws.ec2metadata 0.2.0 * revise timeout for curl checks against instance metadata (Thanks @jmorten) diff --git a/R/aws.ec2metadata-package.R b/R/aws.ec2metadata-package.R index 46c467b..0430918 100644 --- a/R/aws.ec2metadata-package.R +++ b/R/aws.ec2metadata-package.R @@ -12,10 +12,12 @@ get_timeout <- function(default_timeout="1") { return(timeout*1000) } -fetch <- function(uri) { +fetch <- function(uri, token=NULL) { timeout <- get_timeout() handle <- curl::new_handle(timeout_ms = timeout) - + if(!is.null(token)) { + curl::handle_setheaders(handle, 'X-aws-ec2-metadata-token' = token) + } response <- try( curl::curl_fetch_memory(uri, handle = handle), @@ -30,17 +32,36 @@ fetch <- function(uri) { } +# for IMDSv2 + +fetch_token <- function(base_url, version) { + timeout <- get_timeout() + handle <- curl::new_handle(timeout_ms=timeout) + curl::handle_setheaders(handle, "X-aws-ec2-metadata-token-ttl-seconds" = "21600") + curl::handle_setopt(handle, customrequest = 'PUT') + uri <- paste0(base_url, version, '/api/token'); + response <- curl::curl_fetch_memory(uri, handle = handle) + rawToChar(response$content) +} + get_instance_metadata <- function(item, version = "latest", base_url = "http://169.254.169.254/", parse = "text", ...) { + + use_token <- Sys.getenv('USE_IMDS_TOKEN') == "TRUE" if (!missing(item)) { uri <- paste0(base_url, version, "/", item) } else { uri <- base_url } - response <- fetch(uri) + if(use_token) { + token <- fetch_token(base_url, version) + response <- fetch(uri, token) + } else { + response <- fetch(uri) + } if (is.null(response)) { stop("Request failed", call. = FALSE) } else if (response[["status_code"]] >= 400) { diff --git a/README.md b/README.md index 3c8dc15..3bc0344 100644 --- a/README.md +++ b/README.md @@ -47,5 +47,14 @@ if (!require("remotes")) { remotes::install_github("cloudyr/aws.ec2metadata") ``` +## IMDSv2 support + +For IMDSv2, a token is required. Details in aws support [here](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html). +Set environment variable USE_IMDS_TOKEN to "TRUE" to use this feature. + +```R +Sys.setenv(USE_IMDS_TOKEN="TRUE") +``` + --- [![cloudyr project logo](https://i.imgur.com/JHS98Y7.png)](https://github.com/cloudyr) diff --git a/man/ec2metadata.Rd b/man/ec2metadata.Rd index 2af7da4..cab605a 100644 --- a/man/ec2metadata.Rd +++ b/man/ec2metadata.Rd @@ -10,7 +10,9 @@ \alias{is_ecs} \alias{ecs_metadata} \title{Get EC2 Instance Metadata} -\format{An object of class \code{list} of length 26.} +\format{ +An object of class \code{list} of length 26. +} \usage{ is_ec2()