From ec9992562bec1f2b5c0275f0e59926a3b088daa2 Mon Sep 17 00:00:00 2001 From: Fran Barton Date: Thu, 26 Mar 2026 15:08:03 +0000 Subject: [PATCH] :broom: Refactor the imds_available routine Should close #97 --- R/get_auth_token.R | 79 +++++++++++++++++++++---------------------- man/imds_available.Rd | 4 +-- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/R/get_auth_token.R b/R/get_auth_token.R index 7184fd2..dda963d 100644 --- a/R/get_auth_token.R +++ b/R/get_auth_token.R @@ -261,57 +261,56 @@ generate_resource <- function( } -#' Use a token's internal `refresh()` method to refresh it -#' -#' This method avoids the need to refresh by re-authenticating online. It seems -#' like this only works with v1 tokens. v2 tokens always seem to refresh by -#' re-authenticating with Azure online. But v2 tokens _ought_ to refresh -#' automatically and not need manual refreshing. To instead generate a -#' completely fresh token, pass `use_cache = FALSE` or `force_refresh = TRUE` -#' to [get_auth_token]. -#' @param token An Azure authentication token -#' @returns An Azure authentication token -#' @export -refresh_token <- \(token) token$refresh() - #' Check if Azure Instance Metadata Service (IMDS) is Available #' #' This function checks if the Azure Instance Metadata Service (IMDS) is -#' available by attempting to make a request to the IMDS endpoint. The result is -#' cached in an environment variable for future use, saving the need for -#' repeated checks. +#' available by attempting to make a request to the IMDS endpoint. The result +#' is cached in an environment variable for future use, saving the need for +#' repeated checks. #' #' You can also set the `IMDS_AVAILABLE` environment variable manually to -#' "TRUE" or "FALSE" to override the automatic check, which can be useful for -#' testing or in environments where the check may not work correctly. +#' "TRUE" or "FALSE" to override the automatic check, which can be useful for +#' testing or in environments where the check may not work correctly. imds_available <- function() { available <- Sys.getenv("IMDS_AVAILABLE") if (available == "") { - available <- tryCatch( - { - Sys.getenv( - "MSI_ENDPOINT", - "http://169.254.169.254/metadata/identity/oauth2" - ) |> - httr2::request() |> - httr2::req_headers(Metadata = "true") |> - httr2::req_timeout(0.2) |> - httr2::req_perform() - - TRUE - }, - error = function(e) FALSE - ) + possibly_ping_msi_endpoint <- purrr::possibly(ping_msi_endpoint, FALSE) + available <- possibly_ping_msi_endpoint() Sys.setenv(IMDS_AVAILABLE = available) } - - switch(toupper(available), "TRUE" = TRUE, "FALSE" = FALSE, { - warning( - "Invalid value for IMDS_AVAILABLE environment variable: ", - available, - ". Expected 'true' or 'false'. Defaulting to FALSE." + if (is.na(as.logical(available))) { + cli::cli_alert_warning( + "Invalid value for IMDS_AVAILABLE environment variable: {available}.", + "Expected 'TRUE' or 'FALSE'. Defaulting to FALSE." ) FALSE - }) + } else { + available + } } + + +ping_msi_endpoint <- function() { + fallback_url <- "http://169.254.169.254/metadata/identity/oauth2" + Sys.getenv("MSI_ENDPOINT", fallback_url) |> + httr2::request() |> + httr2::req_headers(Metadata = "true") |> + httr2::req_timeout(0.2) |> + httr2::req_perform() + TRUE +} + + +#' Use a token's internal `refresh()` method to refresh it +#' +#' This method avoids the need to refresh by re-authenticating online. It seems +#' like this only works with v1 tokens. v2 tokens always seem to refresh by +#' re-authenticating with Azure online. But v2 tokens _ought_ to refresh +#' automatically and not need manual refreshing. To instead generate a +#' completely fresh token, pass `use_cache = FALSE` or `force_refresh = TRUE` +#' to [get_auth_token]. +#' @param token An Azure authentication token +#' @returns An Azure authentication token +#' @export +refresh_token <- \(token) token$refresh() diff --git a/man/imds_available.Rd b/man/imds_available.Rd index 22abcc6..53334a9 100644 --- a/man/imds_available.Rd +++ b/man/imds_available.Rd @@ -8,8 +8,8 @@ imds_available() } \description{ This function checks if the Azure Instance Metadata Service (IMDS) is -available by attempting to make a request to the IMDS endpoint. The result is -cached in an environment variable for future use, saving the need for +available by attempting to make a request to the IMDS endpoint. The result +is cached in an environment variable for future use, saving the need for repeated checks. } \details{