From 26b25f9703847192b5f86c35285d8031e347026e Mon Sep 17 00:00:00 2001 From: Jason Latta Date: Fri, 27 Jun 2025 08:50:39 -0600 Subject: [PATCH 01/12] Add bedrock endpoints to gov cloud partition --- priv/endpoints.exs | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/priv/endpoints.exs b/priv/endpoints.exs index eecc8978..677da665 100644 --- a/priv/endpoints.exs +++ b/priv/endpoints.exs @@ -3122,6 +3122,65 @@ chime_voice_regions = [ "us-gov-west-1" => %{"description" => "AWS GovCloud (US-West)"} }, "services" => %{ + "bedrock" => %{ + "endpoints" => %{ + "us-gov-east-1" => %{}, + "us-gov-east-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-east-1"}, + "hostname" => "bedrock-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" => %{}, + "us-gov-west-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-west-1"}, + "hostname" => "bedrock-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "bedrock-runtime" => %{ + "defaults" => %{"credentialScope" => %{"service" => "bedrock"}}, + "endpoints" => %{ + "us-gov-east-1" => %{}, + "us-gov-east-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-east-1"}, + "hostname" => "bedrock-runtime-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" => %{}, + "us-gov-west-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-west-1"}, + "hostname" => "bedrock-runtime-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "bedrock-agent" => %{ + "defaults" => %{"credentialScope" => %{"service" => "bedrock"}}, + "endpoints" => %{ + "us-gov-east-1" => %{}, + "us-gov-east-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-east-1"}, + "hostname" => "bedrock-agent-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" => %{}, + "us-gov-west-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-west-1"}, + "hostname" => "bedrock-agent-fips.us-gov-west-1.amazonaws.com" + } + } + }, + "bedrock-agent-runtime" => %{ + "defaults" => %{"credentialScope" => %{"service" => "bedrock"}}, + "endpoints" => %{ + "us-gov-east-1" => %{}, + "us-gov-east-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-east-1"}, + "hostname" => "bedrock-agent-runtime-fips.us-gov-east-1.amazonaws.com" + }, + "us-gov-west-1" => %{}, + "us-gov-west-1-fips" => %{ + "credentialScope" => %{"region" => "us-gov-west-1"}, + "hostname" => "bedrock-agent-runtime-fips.us-gov-west-1.amazonaws.com" + } + } + }, "elasticache" => %{"endpoints" => %{"us-gov-east-1" => %{}, "us-gov-west-1" => %{}}}, "fsx" => %{ "endpoints" => %{ From d8568f6b734fe32973e5a562a986071fbffca44f Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Mon, 14 Jul 2025 07:09:45 -1000 Subject: [PATCH 02/12] Refresh session tokens --- lib/ex_aws/credentials_ini/file.ex | 111 +++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 7 deletions(-) diff --git a/lib/ex_aws/credentials_ini/file.ex b/lib/ex_aws/credentials_ini/file.ex index 41f1f3b1..8b732a07 100644 --- a/lib/ex_aws/credentials_ini/file.ex +++ b/lib/ex_aws/credentials_ini/file.ex @@ -46,15 +46,14 @@ if Code.ensure_loaded?(ConfigParser) do with {_, {:ok, sso_cache_content}} <- {:read, File.read(get_sso_cache_file(sso_cache_key))}, {_, - {:ok, %{"expiresAt" => expires_at, "accessToken" => access_token, "region" => region}}} <- + {:ok, %{"expiresAt" => expires_at} = sso_cache}} <- {:decode, config[:json_codec].decode(sso_cache_content)}, {_, :ok} <- {:expiration, check_sso_expiration(expires_at)}, {_, {:ok, sso_creds}} <- {:sso_creds, request_sso_role_credentials( - access_token, - region, + sso_cache, sso_account_id, sso_role_name, config @@ -65,6 +64,15 @@ if Code.ensure_loaded?(ConfigParser) do else {:read, {:error, error}} -> {:error, "Could not read SSO cache file: #{error}"} {:decode, _} -> {:error, "SSO cache file contains invalid json"} + {:expiration, {:error, :expired_token}} -> + case get_sso_cache_with_refresh(sso_cache_key, sso_account_id, sso_role_name, config) do + {:ok, sso_creds} -> + case rename_sso_credential_keys(sso_creds) do + {:ok, reformatted_creds} -> {:ok, reformatted_creds} + {:error, error} -> {:error, error} + end + {:error, error} -> {:error, error} + end {:expiration, error} -> error {:sso_creds, error} -> error {:rename, error} -> error @@ -78,6 +86,25 @@ if Code.ensure_loaded?(ConfigParser) do |> Path.join(".aws/sso/cache/#{hash}.json") end + defp get_sso_cache_with_refresh(sso_cache_key, sso_account_id, sso_role_name, config) do + with {_, {:ok, sso_cache_content}} <- + {:read, File.read(get_sso_cache_file(sso_cache_key))}, + {_, {:ok, sso_cache}} <- + {:decode, config[:json_codec].decode(sso_cache_content)}, + {_, {:ok, new_access_token}} <- + {:refresh, refresh_access_token(sso_cache, sso_cache["region"], config)}, + {_, {:ok, sso_creds}} <- + {:sso_creds, + make_sso_request(new_access_token, sso_cache["region"], sso_account_id, sso_role_name, config)} do + {:ok, sso_creds} + else + {:read, {:error, error}} -> {:error, "Could not read SSO cache file: #{error}"} + {:decode, _} -> {:error, "SSO cache file contains invalid json"} + {:refresh, {:error, error}} -> {:error, "Failed to refresh access token: #{error}"} + {:sso_creds, error} -> error + end + end + defp check_sso_expiration(expires_at_str) do with {:ok, _} <- check_expiration(expires_at_str) do :ok @@ -86,17 +113,40 @@ if Code.ensure_loaded?(ConfigParser) do {:error, "SSO cache file has invalid expiration format: #{err}"} {:expires, _} -> - {:error, "SSO access token is expired, refresh the token with `aws sso login`"} + {:error, :expired_token} end end defp request_sso_role_credentials( - access_token, - region, + sso_cache, account_id, role_name, config ) do + %{ + "accessToken" => access_token, + "region" => region + } = sso_cache + + case make_sso_request(access_token, region, account_id, role_name, config) do + {:ok, result} -> + {:ok, result} + + {:error, :expired_token} -> + case refresh_access_token(sso_cache, region, config) do + {:ok, new_access_token} -> + make_sso_request(new_access_token, region, account_id, role_name, config) + + {:error, refresh_error} -> + {:error, "Failed to refresh access token: #{refresh_error}"} + end + + {:error, other_error} -> + {:error, other_error} + end + end + + defp make_sso_request(access_token, region, account_id, role_name, config) do with {_, {:ok, %{status_code: 200, headers: _headers, body: body_raw}}} <- {:request, config[:http_client].request( @@ -110,14 +160,61 @@ if Code.ensure_loaded?(ConfigParser) do {_, {:ok, body}} <- {:decode, config[:json_codec].decode(body_raw)} do {:ok, body} else + {:request, {_, %{body: body, status_code: 401}} = resp} -> + case config[:json_codec].decode(body) do + {:ok, %{"message" => "Session token not found or invalid"}} -> + {:error, :expired_token} + + _ -> + {:error, "SSO role credentials request responded with 401: #{inspect(resp)}"} + end + {:request, {_, %{status_code: status_code} = resp}} -> - {:error, "SSO role credentials request responded with #{status_code}: #{resp}"} + {:error, "SSO role credentials request responded with #{status_code}: #{inspect(resp)}"} {:decode, err} -> {:error, "Could not decode SSO role credentials response: #{err}"} end end + defp refresh_access_token(sso_cache, region, config) do + body_map = %{ + "grantType" => "refresh_token", + "clientId" => sso_cache["clientId"], + "clientSecret" => sso_cache["clientSecret"], + "refreshToken" => sso_cache["refreshToken"] + } + + headers = [ + {"Content-Type", "application/json"} + ] + + {:ok, body} = config[:json_codec].encode(body_map) + + with {:ok, %{status_code: 200, body: body_raw}} <- + config[:http_client].request( + :post, + "https://oidc.#{region}.amazonaws.com/token", + body, + headers, + Map.get(config, :http_opts, []) + ) + |> ExAws.Request.maybe_transform_response(), + {:ok, %{"accessToken" => new_access_token}} <- + config[:json_codec].decode(body_raw) do + {:ok, new_access_token} + else + {:error, _} = error -> + error + + {_, %{status_code: status_code, body: body}} -> + {:error, "Token refresh failed with status #{status_code}: #{body}"} + + {_, _} -> + {:error, "Failed to parse refresh token response"} + end + end + defp rename_sso_credential_keys(%{"roleCredentials" => role_credentials}) do with {_, access_key} when not is_nil(access_key) <- {:accessKey, Map.get(role_credentials, "accessKeyId")}, From fe488e67d11d18308882599c88473a5f6d9e7dcc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 14 Jul 2025 17:23:24 +0000 Subject: [PATCH 03/12] Bump req from 0.5.10 to 0.5.15 Bumps [req](https://github.com/wojtekmach/req) from 0.5.10 to 0.5.15. - [Release notes](https://github.com/wojtekmach/req/releases) - [Changelog](https://github.com/wojtekmach/req/blob/main/CHANGELOG.md) - [Commits](https://github.com/wojtekmach/req/compare/v0.5.10...v0.5.15) --- updated-dependencies: - dependency-name: req dependency-version: 0.5.15 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- mix.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mix.lock b/mix.lock index caee27dd..6226a4a2 100644 --- a/mix.lock +++ b/mix.lock @@ -11,9 +11,9 @@ "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, "excoveralls": {:hex, :excoveralls, "0.18.5", "e229d0a65982613332ec30f07940038fe451a2e5b29bce2a5022165f0c9b157e", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "523fe8a15603f86d64852aab2abe8ddbd78e68579c8525ae765facc5eae01562"}, - "finch": {:hex, :finch, "0.19.0", "c644641491ea854fc5c1bbaef36bfc764e3f08e7185e1f084e35e0672241b76d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "fc5324ce209125d1e2fa0fcd2634601c52a787aff1cd33ee833664a5af4ea2b6"}, + "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, "hackney": {:hex, :hackney, "1.24.1", "f5205a125bba6ed4587f9db3cc7c729d11316fa8f215d3e57ed1c067a9703fa9", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "f4a7392a0b53d8bbc3eb855bdcc919cd677358e65b2afd3840b5b3690c4c8a39"}, - "hpax": {:hex, :hpax, "1.0.2", "762df951b0c399ff67cc57c3995ec3cf46d696e41f0bba17da0518d94acd4aac", [:mix], [], "hexpm", "2f09b4c1074e0abd846747329eaa26d535be0eb3d189fa69d812bfb8bfefd32f"}, + "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, "jsx": {:hex, :jsx, "3.1.0", "d12516baa0bb23a59bb35dccaf02a1bd08243fcbb9efe24f2d9d056ccff71268", [:rebar3], [], "hexpm", "0c5cc8fdc11b53cc25cf65ac6705ad39e54ecc56d1c22e4adb8f5a53fb9427f3"}, @@ -21,7 +21,7 @@ "makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"}, "makeup_erlang": {:hex, :makeup_erlang, "1.0.2", "03e1804074b3aa64d5fad7aa64601ed0fb395337b982d9bcf04029d68d51b6a7", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "af33ff7ef368d5893e4a267933e7744e46ce3cf1f61e2dccf53a111ed3aa3727"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, - "mime": {:hex, :mime, "2.0.6", "8f18486773d9b15f95f4f4f1e39b710045fa1de891fada4516559967276e4dc2", [:mix], [], "hexpm", "c9945363a6b26d747389aac3643f8e0e09d30499a138ad64fe8fd1d13d9b153e"}, + "mime": {:hex, :mime, "2.0.7", "b8d739037be7cd402aee1ba0306edfdef982687ee7e9859bee6198c1e7e2f128", [:mix], [], "hexpm", "6171188e399ee16023ffc5b76ce445eb6d9672e2e241d2df6050f3c771e80ccd"}, "mimerl": {:hex, :mimerl, "1.4.0", "3882a5ca67fbbe7117ba8947f27643557adec38fa2307490c4c4207624cb213b", [:rebar3], [], "hexpm", "13af15f9f68c65884ecca3a3891d50a7b57d82152792f3e19d88650aa126b144"}, "mint": {:hex, :mint, "1.7.1", "113fdb2b2f3b59e47c7955971854641c61f378549d73e829e1768de90fc1abf1", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1 or ~> 0.2.0 or ~> 1.0", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "fceba0a4d0f24301ddee3024ae116df1c3f4bb7a563a731f45fdfeb9d39a231b"}, "mox": {:hex, :mox, "1.2.0", "a2cd96b4b80a3883e3100a221e8adc1b98e4c3a332a8fc434c39526babafd5b3", [:mix], [{:nimble_ownership, "~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}], "hexpm", "c7b92b3cc69ee24a7eeeaf944cd7be22013c52fcb580c1f33f50845ec821089a"}, @@ -30,11 +30,11 @@ "nimble_parsec": {:hex, :nimble_parsec, "1.4.2", "8efba0122db06df95bfaa78f791344a89352ba04baedd3849593bfce4d0dc1c6", [:mix], [], "hexpm", "4b21398942dda052b403bbe1da991ccd03a053668d147d53fb8c4e0efe09c973"}, "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"}, - "plug": {:hex, :plug, "1.17.0", "a0832e7af4ae0f4819e0c08dd2e7482364937aea6a8a997a679f2cbb7e026b2e", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f6692046652a69a00a5a21d0b7e11fcf401064839d59d6b8787f23af55b1e6bc"}, + "plug": {:hex, :plug, "1.18.1", "5067f26f7745b7e31bc3368bc1a2b818b9779faa959b49c934c17730efc911cf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "57a57db70df2b422b564437d2d33cf8d33cd16339c1edb190cd11b1a3a546cc2"}, "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"}, - "plug_crypto": {:hex, :plug_crypto, "2.1.0", "f44309c2b06d249c27c8d3f65cfe08158ade08418cf540fd4f72d4d6863abb7b", [:mix], [], "hexpm", "131216a4b030b8f8ce0f26038bc4421ae60e4bb95c5cf5395e1421437824c4fa"}, + "plug_crypto": {:hex, :plug_crypto, "2.1.1", "19bda8184399cb24afa10be734f84a16ea0a2bc65054e23a62bb10f06bc89491", [:mix], [], "hexpm", "6470bce6ffe41c8bd497612ffde1a7e4af67f36a15eea5f921af71cf3e11247c"}, "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, - "req": {:hex, :req, "0.5.10", "a3a063eab8b7510785a467f03d30a8d95f66f5c3d9495be3474b61459c54376c", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "8a604815743f8a2d3b5de0659fa3137fa4b1cffd636ecb69b30b2b9b2c2559be"}, + "req": {:hex, :req, "0.5.15", "662020efb6ea60b9f0e0fac9be88cd7558b53fe51155a2d9899de594f9906ba9", [:mix], [{:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 2.0.6 or ~> 2.1", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "a6513a35fad65467893ced9785457e91693352c70b58bbc045b47e5eb2ef0c53"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, "sweet_xml": {:hex, :sweet_xml, "0.7.5", "803a563113981aaac202a1dbd39771562d0ad31004ddbfc9b5090bdcd5605277", [:mix], [], "hexpm", "193b28a9b12891cae351d81a0cead165ffe67df1b73fe5866d10629f4faefb12"}, "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, From e51bd41f4b4956fdcb36c78a8fe60ae13ac5b441 Mon Sep 17 00:00:00 2001 From: Riivo Parts Date: Fri, 1 Aug 2025 14:58:18 +0300 Subject: [PATCH 04/12] Add Redshift Data API endpoints Redshift data API is used for interacting with data in Redshift warehouse. The redshift endpoints are for infrastructure management instead. Adds capabilities to use Redshift Data API documented here: [redshift-data] [redshift-data]: https://docs.aws.amazon.com/redshift-data/latest/APIReference/Welcome.html --- priv/endpoints.exs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/priv/endpoints.exs b/priv/endpoints.exs index eecc8978..b6e1c153 100644 --- a/priv/endpoints.exs +++ b/priv/endpoints.exs @@ -2227,6 +2227,29 @@ chime_voice_regions = [ "us-west-2" => %{} } }, + "redshift-data" => %{ + "endpoints" => %{ + "ap-northeast-1" => %{}, + "ap-northeast-2" => %{}, + "ap-east-1" => %{}, + "ap-south-1" => %{}, + "ap-south-2" => %{}, + "ap-southeast-1" => %{}, + "ap-southeast-2" => %{}, + "ca-central-1" => %{}, + "ca-west-1" => %{}, + "eu-central-1" => %{}, + "eu-west-1" => %{}, + "eu-west-2" => %{}, + "eu-west-3" => %{}, + "eu-north-1" => %{}, + "sa-east-1" => %{}, + "us-east-1" => %{}, + "us-east-2" => %{}, + "us-west-1" => %{}, + "us-west-2" => %{} + } + }, "email" => %{ "endpoints" => %{ "af-south-1" => %{}, @@ -3087,6 +3110,7 @@ chime_voice_regions = [ }, "tagging" => %{"endpoints" => %{"cn-north-1" => %{}, "cn-northwest-1" => %{}}}, "redshift" => %{"endpoints" => %{"cn-north-1" => %{}, "cn-northwest-1" => %{}}}, + "redshift-data" => %{"endpoints" => %{"cn-north-1" => %{}, "cn-northwest-1" => %{}}}, "storagegateway" => %{"endpoints" => %{"cn-north-1" => %{}}}, "autoscaling" => %{ "defaults" => %{"protocols" => ["http", "https"]}, @@ -3285,6 +3309,7 @@ chime_voice_regions = [ }, "tagging" => %{"endpoints" => %{"us-gov-east-1" => %{}, "us-gov-west-1" => %{}}}, "redshift" => %{"endpoints" => %{"us-gov-east-1" => %{}, "us-gov-west-1" => %{}}}, + "redshift-data" => %{"endpoints" => %{"us-gov-east-1" => %{}, "us-gov-west-1" => %{}}}, "storagegateway" => %{"endpoints" => %{"us-gov-east-1" => %{}, "us-gov-west-1" => %{}}}, "autoscaling" => %{ "endpoints" => %{ From ddcc436f7bfbea4f3a77ce90787ad8fbc2cc47be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Aug 2025 04:27:49 +0000 Subject: [PATCH 05/12] Bump hackney from 1.24.1 to 1.25.0 Bumps [hackney](https://github.com/benoitc/hackney) from 1.24.1 to 1.25.0. - [Release notes](https://github.com/benoitc/hackney/releases) - [Changelog](https://github.com/benoitc/hackney/blob/master/NEWS.md) - [Commits](https://github.com/benoitc/hackney/compare/1.24.1...1.25.0) --- updated-dependencies: - dependency-name: hackney dependency-version: 1.25.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 6226a4a2..d78c57fb 100644 --- a/mix.lock +++ b/mix.lock @@ -12,7 +12,7 @@ "ex_doc": {:hex, :ex_doc, "0.38.2", "504d25eef296b4dec3b8e33e810bc8b5344d565998cd83914ffe1b8503737c02", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "732f2d972e42c116a70802f9898c51b54916e542cc50968ac6980512ec90f42b"}, "excoveralls": {:hex, :excoveralls, "0.18.5", "e229d0a65982613332ec30f07940038fe451a2e5b29bce2a5022165f0c9b157e", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "523fe8a15603f86d64852aab2abe8ddbd78e68579c8525ae765facc5eae01562"}, "finch": {:hex, :finch, "0.20.0", "5330aefb6b010f424dcbbc4615d914e9e3deae40095e73ab0c1bb0968933cadf", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.6.2 or ~> 1.7", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 1.1", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2658131a74d051aabfcba936093c903b8e89da9a1b63e430bee62045fa9b2ee2"}, - "hackney": {:hex, :hackney, "1.24.1", "f5205a125bba6ed4587f9db3cc7c729d11316fa8f215d3e57ed1c067a9703fa9", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "f4a7392a0b53d8bbc3eb855bdcc919cd677358e65b2afd3840b5b3690c4c8a39"}, + "hackney": {:hex, :hackney, "1.25.0", "390e9b83f31e5b325b9f43b76e1a785cbdb69b5b6cd4e079aa67835ded046867", [:rebar3], [{:certifi, "~> 2.15.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.4", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.4.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "7209bfd75fd1f42467211ff8f59ea74d6f2a9e81cbcee95a56711ee79fd6b1d4"}, "hpax": {:hex, :hpax, "1.0.3", "ed67ef51ad4df91e75cc6a1494f851850c0bd98ebc0be6e81b026e765ee535aa", [:mix], [], "hexpm", "8eab6e1cfa8d5918c2ce4ba43588e894af35dbd8e91e6e55c817bca5847df34a"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, From bd0877cb5fedef80dc4922cc3ec7e1a16ba3f240 Mon Sep 17 00:00:00 2001 From: Bernard Duggan Date: Tue, 12 Aug 2025 10:51:38 +1000 Subject: [PATCH 06/12] Update version and changelog. v2.5.11 --- CHANGELOG.md | 3 +++ mix.exs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b4a5549..9a893dea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +v2.5.11 (2025-08-12) +- Endpoint updates + v2.5.10 (2025-06-16) - Fix crash on SSO credentials error - Fix type error on `ExAws.Operation.RestQuery.stream!2` diff --git a/mix.exs b/mix.exs index a198befb..3be3ae08 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule ExAws.Mixfile do use Mix.Project @source_url "https://github.com/ex-aws/ex_aws" - @version "2.5.10" + @version "2.5.11" def project do [ From 1bf4a9787ae2fef98643e8f70cbc68cabfe71af6 Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Tue, 16 Sep 2025 18:32:53 -1000 Subject: [PATCH 07/12] Fix geo operations for places and routes --- lib/ex_aws/config/defaults.ex | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/ex_aws/config/defaults.ex b/lib/ex_aws/config/defaults.ex index 10d60c08..495e7d18 100644 --- a/lib/ex_aws/config/defaults.ex +++ b/lib/ex_aws/config/defaults.ex @@ -77,7 +77,17 @@ defmodule ExAws.Config.Defaults do |> Map.merge(defaults(:timestream)) end - def defaults(service) when service in [:places, :maps, :geofencing, :tracking, :routes] do + def defaults(:places) do + %{service_override: :"geo-places"} + |> Map.merge(defaults(:geo)) + end + + def defaults(:routes) do + %{service_override: :"geo-routes"} + |> Map.merge(defaults(:geo)) + end + + def defaults(service) when service in [:maps, :geofencing, :tracking] do %{service_override: :geo} |> Map.merge(defaults(:geo)) end From 076ba263d163099f0b2c5ce52216f4b87117177e Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Mon, 22 Sep 2025 10:56:12 -1000 Subject: [PATCH 08/12] Fix govcloud partition Specifically: `(RuntimeError) places not found in partition aws-us-gov` --- lib/ex_aws/config/defaults.ex | 20 +++++++++++++++----- priv/endpoints.exs | 5 +++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/ex_aws/config/defaults.ex b/lib/ex_aws/config/defaults.ex index 495e7d18..cbeaf970 100644 --- a/lib/ex_aws/config/defaults.ex +++ b/lib/ex_aws/config/defaults.ex @@ -79,17 +79,27 @@ defmodule ExAws.Config.Defaults do def defaults(:places) do %{service_override: :"geo-places"} - |> Map.merge(defaults(:geo)) + |> Map.merge(defaults(:"geo-places")) end def defaults(:routes) do %{service_override: :"geo-routes"} - |> Map.merge(defaults(:geo)) + |> Map.merge(defaults(:"geo-routes")) end - def defaults(service) when service in [:maps, :geofencing, :tracking] do - %{service_override: :geo} - |> Map.merge(defaults(:geo)) + def defaults(:maps) do + %{service_override: :"geo-maps"} + |> Map.merge(defaults(:"geo-maps")) + end + + def defaults(:geofencing) do + %{service_override: :"geo-geofencing"} + |> Map.merge(defaults(:"geo-geofencing")) + end + + def defaults(:tracking) do + %{service_override: :"geo-tracking"} + |> Map.merge(defaults(:"geo-tracking")) end def defaults(chime_service) diff --git a/priv/endpoints.exs b/priv/endpoints.exs index 11dde44b..3fdeb060 100644 --- a/priv/endpoints.exs +++ b/priv/endpoints.exs @@ -3400,6 +3400,11 @@ chime_voice_regions = [ "cloudformation" => %{"endpoints" => %{"us-gov-east-1" => %{}, "us-gov-west-1" => %{}}}, "swf" => %{"endpoints" => %{"us-gov-east-1" => %{}, "us-gov-west-1" => %{}}}, "sagemaker" => %{"endpoints" => %{"us-gov-west-1" => %{}}}, + "places.geo" => %{ + "endpoints" => %{ + "us-gov-west-1" => %{} + } + }, "sso" => %{ "endpoints" => %{ "us-gov-east-1" => %{}, From 6dfc03386ed4dce8548d96a9bc459e2d02e2ddb6 Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Mon, 29 Sep 2025 17:11:22 -1000 Subject: [PATCH 09/12] Update service definitions --- lib/ex_aws/config/defaults.ex | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/lib/ex_aws/config/defaults.ex b/lib/ex_aws/config/defaults.ex index cbeaf970..d70bb4b1 100644 --- a/lib/ex_aws/config/defaults.ex +++ b/lib/ex_aws/config/defaults.ex @@ -77,31 +77,21 @@ defmodule ExAws.Config.Defaults do |> Map.merge(defaults(:timestream)) end - def defaults(:places) do + def defaults(service) when service in [:places, :maps, :geofencing, :tracking, :routes] do + %{service_override: :geo} + |> Map.merge(defaults(:geo)) + end + + def defaults(:places_v2) do %{service_override: :"geo-places"} |> Map.merge(defaults(:"geo-places")) end - def defaults(:routes) do + def defaults(:routes_v2) do %{service_override: :"geo-routes"} |> Map.merge(defaults(:"geo-routes")) end - def defaults(:maps) do - %{service_override: :"geo-maps"} - |> Map.merge(defaults(:"geo-maps")) - end - - def defaults(:geofencing) do - %{service_override: :"geo-geofencing"} - |> Map.merge(defaults(:"geo-geofencing")) - end - - def defaults(:tracking) do - %{service_override: :"geo-tracking"} - |> Map.merge(defaults(:"geo-tracking")) - end - def defaults(chime_service) when chime_service in [ :"chime-sdk-media-pipelines", @@ -157,11 +147,11 @@ defmodule ExAws.Config.Defaults do defp service_map(:iot_data), do: "data.iot" defp service_map(:ingest_timestream), do: "ingest.timestream" defp service_map(:query_timestream), do: "query.timestream" - defp service_map(:places), do: "places.geo" + defp service_map(place_service) when place_service in [:places, :places_v2], do: "places.geo" defp service_map(:maps), do: "maps.geo" defp service_map(:geofencing), do: "geofencing.geo" defp service_map(:tracking), do: "tracking.geo" - defp service_map(:routes), do: "routes.geo" + defp service_map(route_service) when route_service in [:routes, :routes_v2], do: "routes.geo" defp service_map(service) do service From c33a853632164d3358dbf85cc11dd48a5013001c Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Tue, 30 Sep 2025 15:34:38 -1000 Subject: [PATCH 10/12] bump for testing --- lib/ex_aws.ex | 4 ++++ mix.exs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/ex_aws.ex b/lib/ex_aws.ex index ea4fbfea..333cf7e7 100644 --- a/lib/ex_aws.ex +++ b/lib/ex_aws.ex @@ -7,6 +7,10 @@ defmodule ExAws do @behaviour ExAws.Behaviour + def demo do + 43 + end + @doc """ Perform an AWS request. diff --git a/mix.exs b/mix.exs index 3be3ae08..f8521f65 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule ExAws.Mixfile do use Mix.Project @source_url "https://github.com/ex-aws/ex_aws" - @version "2.5.11" + @version "2.5.13" def project do [ From 0c6c4f3d3bef00b2ca02cb86090d84a6a08d6bb5 Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Tue, 30 Sep 2025 16:58:20 -1000 Subject: [PATCH 11/12] enable routing for govcloud --- priv/endpoints.exs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/priv/endpoints.exs b/priv/endpoints.exs index 3fdeb060..84123a27 100644 --- a/priv/endpoints.exs +++ b/priv/endpoints.exs @@ -3405,6 +3405,11 @@ chime_voice_regions = [ "us-gov-west-1" => %{} } }, + "routes.geo" => %{ + "endpoints" => %{ + "us-gov-west-1" => %{} + } + }, "sso" => %{ "endpoints" => %{ "us-gov-east-1" => %{}, From b60ac9d65744f13b33106d9723966b15b31a770e Mon Sep 17 00:00:00 2001 From: Jason Axelson Date: Tue, 30 Sep 2025 16:58:20 -1000 Subject: [PATCH 12/12] enable routing for govcloud --- priv/endpoints.exs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/priv/endpoints.exs b/priv/endpoints.exs index 3fdeb060..84123a27 100644 --- a/priv/endpoints.exs +++ b/priv/endpoints.exs @@ -3405,6 +3405,11 @@ chime_voice_regions = [ "us-gov-west-1" => %{} } }, + "routes.geo" => %{ + "endpoints" => %{ + "us-gov-west-1" => %{} + } + }, "sso" => %{ "endpoints" => %{ "us-gov-east-1" => %{},