Skip to content

Commit 05c6352

Browse files
author
Larefly
authored
Paws.common cran 0.5.2
2 parents be156c8 + eb0e292 commit 05c6352

File tree

5 files changed

+160
-109
lines changed

5 files changed

+160
-109
lines changed

paws.common/DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Package: paws.common
22
Type: Package
33
Title: Paws Low-Level Amazon Web Services API
4-
Version: 0.5.1.9000
4+
Version: 0.5.2
55
Authors@R: c(
66
person("David", "Kretch", email = "[email protected]", role = "aut"),
77
person("Adam", "Banker", email = "[email protected]", role = "aut"),
@@ -54,8 +54,8 @@ Collate:
5454
'service.R'
5555
'custom_dynamodb.R'
5656
'custom_rds.R'
57-
'xmlutil.R'
5857
'util.R'
58+
'xmlutil.R'
5959
'stream.R'
6060
'custom_s3.R'
6161
'error.R'

paws.common/NEWS.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
# paws.common 0.5.1.9000
1+
# paws.common 0.5.2
22

33
* Fix Content-Md5 being modified by user
44
* Add logging system to help with debugging paws issues
55
* Automatically redirect S3 requests when they are initially made to the wrong region; previously these requests would fail
66
* Add support for `AssumeRoleWithWebIdentity` (#477, thanks to @fh-mthomson for contribution)
77
* Clarify that `AWS_CREDENTIAL_EXPIRATION` is optional when using `AWS_SESSION_TOKEN` (#549)
8+
* Add support to IMDSv2 instances (#441, thanks to @jornfranke for contribution)
89

910
# paws.common 0.5.1
1011

paws.common/R/config.R

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,15 @@ get_instance_metadata <- function(query_path = "") {
173173
# Get token timeout for IMDSv2 tokens
174174
token <- "" # Token to be used in case of more secure IMDSv2 authentication
175175
#try IMDSv2 (more information): https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html
176-
metadata_token_url <- file.path(
176+
metadata_token_url <- file.path(
177177
"http://169.254.169.254/latest/api/token"
178178
)
179-
metadata_token_request <-
180-
new_http_request(
181-
"PUT",
182-
metadata_token_url,
183-
timeout = 1,
184-
header=c("X-aws-ec2-metadata-token-ttl-seconds"= token_ttl)
185-
)
179+
metadata_token_request <- new_http_request(
180+
"PUT",
181+
metadata_token_url,
182+
timeout = 1,
183+
header=c("X-aws-ec2-metadata-token-ttl-seconds"= token_ttl)
184+
)
186185

187186
metadata_token_response <- tryCatch(
188187
{
@@ -192,26 +191,24 @@ get_instance_metadata <- function(query_path = "") {
192191
NULL
193192
}
194193
)
195-
if (!(is.null(metadata_token_response)) && metadata_token_response$status_code == 200) {
196-
if (length(metadata_token_response["body"])>0) {
197-
token=rawToChar(metadata_token_response["body"])
198-
}
194+
if (!is.null(metadata_token_response) && metadata_token_response$status_code == 200) {
195+
if (length(metadata_token_response[["body"]])>0) {
196+
token <- rawToChar(metadata_token_response[["body"]])
197+
}
199198
}
200199
metadata_url <- file.path(
201200
"http://169.254.169.254/latest/meta-data",
202201
query_path
203202
)
204203
if (token!="") {
205-
metadata_request <-
206-
new_http_request(
207-
"GET",
208-
metadata_url,
209-
timeout = 1,
210-
header=c("X-aws-ec2-metadata-token"= token)
204+
metadata_request <- new_http_request(
205+
"GET",
206+
metadata_url,
207+
timeout = 1,
208+
header = c("X-aws-ec2-metadata-token"= token)
211209
)
212210
} else {
213-
metadata_request <-
214-
new_http_request("GET", metadata_url, timeout = 1)
211+
metadata_request <- new_http_request("GET", metadata_url, timeout = 1)
215212
}
216213
metadata_response <- tryCatch(
217214
{

paws.common/R/credential_providers.R

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -344,13 +344,12 @@ get_container_credentials <- function() {
344344
credentials_response_body <-
345345
jsonlite::fromJSON(raw_to_utf8(metadata_response$body))
346346

347-
credentials_list <-
348-
list(
349-
access_key_id = credentials_response_body$AccessKeyId,
350-
secret_access_key = credentials_response_body$SecretAccessKey,
351-
session_token = credentials_response_body$Token,
352-
expiration = as_timestamp(credentials_response_body$Expiration, "iso8601"),
353-
)
347+
credentials_list <- list(
348+
access_key_id = credentials_response_body$AccessKeyId,
349+
secret_access_key = credentials_response_body$SecretAccessKey,
350+
session_token = credentials_response_body$Token,
351+
expiration = as_timestamp(credentials_response_body$Expiration, "iso8601")
352+
)
354353

355354
return(credentials_list)
356355
}

paws.common/tests/testthat/test_config.R

Lines changed: 133 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ test_that("get_web_identity_token_file", {
9090
})
9191

9292
test_that("get_instance_metadata_imdsv1", {
93-
# this function mocks the behaviour of the IMDSv1 metadata service in so far as it allows testing of get_instance_metadata in config.
94-
valid_metadata_response="ami-id
93+
# this function mocks the behaviour of the IMDSv1 metadata service in so far
94+
# as it allows testing of get_instance_metadata in config.
95+
valid_metadata_response <- "ami-id
9596
ami-launch-index
9697
ami-manifest-path
9798
block-device-mapping/
@@ -114,46 +115,73 @@ public-keys/
114115
reservation-id
115116
security-groups
116117
services/"
117-
mock_imdsv1_behaviour <- function(http_request) {
118-
# mock behaviour of the imdsv1 metadata service in case it gets an imdsv2 request
119-
if (http_request$url$scheme=="http" && http_request$method=="PUT" && http_request$url$path=="/latest/api/token") {
120-
# ignore this as this only available in IMDSv2.
121-
mock_imdsv1_response_for_imdsv2_request=HttpResponse(
122-
status_code = 404,
123-
header = c("Server"="EC2ws","Connection"="Close", "Content-Type"="text/plain","Content-Length"="0"),
124-
content_length = as.integer("0"),
125-
body = charToRaw("")
126-
)
127-
return (mock_imdsv1_response_for_imdsv2_request)
128-
}
129-
# mock behaviour of the imdsv1 metadata service
130-
if (http_request$url$scheme=="http" && http_request$method=="GET" && http_request$url$path=="/latest/meta-data/") {
131-
# provide response according to IMDSv1
132-
mock_imdsv1_metadata_response=HttpResponse(
133-
status_code = 200,
134-
header = c("Server"="EC2ws","Connection"="Close", "Content-Type"="text/plain","Content-Length"="297"),
135-
content_length = as.integer("297"),
136-
body = charToRaw(valid_metadata_response)
137-
)
138-
return (mock_imdsv1_metadata_response)
139-
}
140-
# if there is an invalid request in general return a HTTP error code
141-
mock_imdsv1_response_invalid_request=HttpResponse(
142-
status_code = 405,
143-
header = c("Server"="EC2ws","Connection"="Close", "Content-Type"="text/plain","Content-Length"="0"),
144-
content_length = as.integer("0"),
145-
body = charToRaw("")
146-
)
147-
return (mock_imdsv1_response_invalid_request)
118+
imdsv1_behaviour <- function(http_request) {
119+
# mock behaviour of the imdsv1 metadata service in case it gets an
120+
# imdsv2 request
121+
if (http_request$url$scheme=="http"
122+
&& http_request$method=="PUT"
123+
&& http_request$url$path=="/latest/api/token") {
124+
# ignore this as this only available in IMDSv2.
125+
mock_imdsv1_response_for_imdsv2_request <- HttpResponse(
126+
status_code = 404,
127+
header = c(
128+
"Server"="EC2ws",
129+
"Connection"="Close",
130+
"Content-Type"="text/plain",
131+
"Content-Length"="0"
132+
),
133+
content_length = 0L,
134+
body = charToRaw("")
135+
)
136+
return (mock_imdsv1_response_for_imdsv2_request)
148137
}
149-
mockery::stub(get_instance_metadata, 'issue', mock_imdsv1_behaviour)
150-
expect_equal(charToRaw(valid_metadata_response),get_instance_metadata()$body)
151-
})
138+
# mock behaviour of the imdsv1 metadata service
139+
if (http_request$url$scheme=="http"
140+
&& http_request$method=="GET"
141+
&& grepl("meta-data", http_request$url$path)) {
142+
# provide response according to IMDSv1
143+
mock_imdsv1_metadata_response <- HttpResponse(
144+
status_code = 200,
145+
header = c(
146+
"Server"="EC2ws",
147+
"Connection"="Close",
148+
"Content-Type"="text/plain",
149+
"Content-Length"="297"
150+
),
151+
content_length = 297L,
152+
body = charToRaw(valid_metadata_response)
153+
)
154+
return (mock_imdsv1_metadata_response)
155+
}
156+
# if there is an invalid request in general return a HTTP error code
157+
mock_imdsv1_response_invalid_request <- HttpResponse(
158+
status_code = 405,
159+
header = c(
160+
"Server"="EC2ws",
161+
"Connection"="Close",
162+
"Content-Type"="text/plain",
163+
"Content-Length"="0"
164+
),
165+
content_length = 0L,
166+
body = charToRaw("")
167+
)
168+
return (mock_imdsv1_response_invalid_request)
169+
}
170+
mock_imdsv1_behaviour <- mock2(side_effect = imdsv1_behaviour)
171+
mockery::stub(get_instance_metadata, 'issue', mock_imdsv1_behaviour)
172+
actual <- get_instance_metadata()
152173

174+
expect_equal(mock_call_no(mock_imdsv1_behaviour), 2)
175+
expect_equal(
176+
charToRaw(valid_metadata_response),
177+
actual$body
178+
)
179+
})
153180

154181
test_that("get_instance_metadata_imdsv2", {
155-
# this function mocks the behaviour of the IMDSv2 metadata service in so far as it allows testing of get_instance_metadata in config.
156-
valid_metadata_response="ami-id
182+
# this function mocks the behaviour of the IMDSv2 metadata service in so far
183+
# as it allows testing of get_instance_metadata in config.
184+
valid_metadata_response <- "ami-id
157185
ami-launch-index
158186
ami-manifest-path
159187
block-device-mapping/
@@ -176,45 +204,71 @@ public-keys/
176204
reservation-id
177205
security-groups
178206
services/"
179-
test_aws_token="AWSTESTINGTokENZZ-XXXXxxxXXXx2XXx1X45XXxXXxX-XxXXxxxXx=="
180-
mock_imdsv2_behaviour <- function(http_request) {
181-
# mock behaviour of the imdsv2 metadata service
182-
if (http_request$url$scheme=="http" && http_request$method=="PUT" && http_request$url$path=="/latest/api/token"
183-
&& !is.na(http_request$header["X-aws-ec2-metadata-token-ttl-seconds"])
184-
&& !is.na(as.numeric(http_request$header[["X-aws-ec2-metadata-token-ttl-seconds"]]))
185-
) {
186-
# provide a valid IMDSv2 metadata service token
187-
mock_imdsv2_token_response=HttpResponse(
188-
status_code = 200,
189-
header = c("Server"="EC2ws","Connection"="Close", "Content-Type"="text/plain","Content-Length"="56"),
190-
content_length = as.integer("56"),
191-
body = charToRaw(test_aws_token)
192-
)
193-
return (mock_imdsv2_token_response)
194-
}
195-
# mock behaviour of the imdsv2 metadata service
196-
if (http_request$url$scheme=="http" && http_request$method=="GET" && http_request$url$path=="/latest/meta-data/"
197-
&& !is.na(http_request$header["X-aws-ec2-metadata-token"])
198-
&& http_request$header[["X-aws-ec2-metadata-token"]]==test_aws_token
199-
) {
200-
# provide response according to IMDSv1
201-
mock_imdsv2_metadata_response=HttpResponse(
202-
status_code = 200,
203-
header = c("Server"="EC2ws","Connection"="Close", "Content-Type"="text/plain","Content-Length"="297","X-Aws-Ec2-Metadata-Token-Ttl-Seconds"="21587"),
204-
content_length = as.integer("297"),
205-
body = charToRaw(valid_metadata_response)
206-
)
207-
return (mock_imdsv2_metadata_response)
208-
}
209-
# if there is an invalid request in general return a HTTP error code
210-
mock_imdsv1_response_invalid_request=HttpResponse(
211-
status_code = 405,
212-
header = c("Server"="EC2ws","Connection"="Close", "Content-Type"="text/plain","Content-Length"="0"),
213-
content_length = as.integer("0"),
214-
body = charToRaw("")
215-
)
216-
return (mock_imdsv1_response_invalid_request)
207+
test_aws_token <- "AWSTESTINGTokENZZ-XXXXxxxXXXx2XXx1X45XXxXXxX-XxXXxxxXx=="
208+
imdsv2_behaviour <- function(http_request) {
209+
# mock behaviour of the imdsv2 metadata service
210+
if (http_request$url$scheme=="http"
211+
&& http_request$method=="PUT"
212+
&& http_request$url$path=="/latest/api/token"
213+
&& !is.na(http_request$header[["X-aws-ec2-metadata-token-ttl-seconds"]])
214+
&& !is.na(as.numeric(http_request$header[["X-aws-ec2-metadata-token-ttl-seconds"]]))
215+
) {
216+
# provide a valid IMDSv2 metadata service token
217+
mock_imdsv2_token_response <- HttpResponse(
218+
status_code = 200,
219+
header = c(
220+
"Server"="EC2ws",
221+
"Connection"="Close",
222+
"Content-Type"="text/plain",
223+
"Content-Length"="56"
224+
),
225+
content_length = 56L,
226+
body = charToRaw(test_aws_token)
227+
)
228+
return (mock_imdsv2_token_response)
229+
}
230+
# mock behaviour of the imdsv2 metadata service
231+
if (http_request$url$scheme=="http"
232+
&& http_request$method=="GET"
233+
&& grepl("meta-data", http_request$url$path)
234+
&& !is.na(http_request$header[["X-aws-ec2-metadata-token"]])
235+
&& http_request$header[["X-aws-ec2-metadata-token"]]==test_aws_token
236+
) {
237+
# provide response according to IMDSv1
238+
mock_imdsv2_metadata_response <- HttpResponse(
239+
status_code = 200,
240+
header = c(
241+
"Server"="EC2ws","Connection"="Close",
242+
"Content-Type"="text/plain",
243+
"Content-Length"="297",
244+
"X-Aws-Ec2-Metadata-Token-Ttl-Seconds"="21587"
245+
),
246+
content_length = 297L,
247+
body = charToRaw(valid_metadata_response)
248+
)
249+
return (mock_imdsv2_metadata_response)
217250
}
218-
mockery::stub(get_instance_metadata, 'issue', mock_imdsv2_behaviour)
219-
expect_equal(charToRaw(valid_metadata_response),get_instance_metadata()$body)
220-
})
251+
# if there is an invalid request in general return a HTTP error code
252+
mock_imdsv1_response_invalid_request <- HttpResponse(
253+
status_code = 405,
254+
header = c(
255+
"Server"="EC2ws",
256+
"Connection"="Close",
257+
"Content-Type"="text/plain",
258+
"Content-Length"="0"
259+
),
260+
content_length = 0L,
261+
body = charToRaw("")
262+
)
263+
return (mock_imdsv1_response_invalid_request)
264+
}
265+
mock_imdsv2_behaviour <- mock2(side_effect = imdsv2_behaviour)
266+
mockery::stub(get_instance_metadata, 'issue', mock_imdsv2_behaviour)
267+
actual <- get_instance_metadata()
268+
269+
expect_equal(mock_call_no(mock_imdsv2_behaviour), 2)
270+
expect_equal(
271+
charToRaw(valid_metadata_response),
272+
actual$body
273+
)
274+
})

0 commit comments

Comments
 (0)