1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
|
%% ====================================================================
%% @author Gavin M. Roy <gavinmroy@gmail.com>
%% @copyright 2016, Gavin M. Roy
%% Copyright (c) 2007-2024 Broadcom. All Rights Reserved. The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. All rights reserved.
%% @headerfile
%% @private
%% @doc rabbitmq_aws client library constants and records
%% @end
%% ====================================================================
-define(MIME_AWS_JSON, "application/x-amz-json-1.0").
-define(SCHEME, https).
-define(DEFAULT_REGION, "us-east-1").
-define(DEFAULT_PROFILE, "default").
-define(INSTANCE_AZ, "placement/availability-zone").
-define(INSTANCE_HOST, "169.254.169.254").
% rabbitmq/rabbitmq-peer-discovery-aws#25
% Note: this timeout must not be greater than the default
% gen_server:call timeout of 5000ms. INSTANCE_HOST is
% a pseudo-ip that should have good performance, and the
% data should be returned quickly. Note that `timeout`,
% when set, is used as the connect and then request timeout
% by `httpc`
-define(DEFAULT_HTTP_TIMEOUT, 2250).
-define(INSTANCE_CREDENTIALS, "iam/security-credentials").
-define(INSTANCE_METADATA_BASE, "latest/meta-data").
-define(INSTANCE_ID, "instance-id").
-define(TOKEN_URL, "latest/api/token").
-define(METADATA_TOKEN_TTL_HEADER, "X-aws-ec2-metadata-token-ttl-seconds").
% EC2 Instance Metadata service version 2 (IMDSv2) uses session-oriented authentication.
% Instance metadata service requests are only needed for loading/refreshing credentials.
% Long-lived EC2 IMDSv2 tokens are unnecessary. The token only needs to be valid long enough
% to successfully load/refresh the credentials. 60 seconds is more than enough time to accomplish this.
-define(METADATA_TOKEN_TTL_SECONDS, 60).
-define(METADATA_TOKEN, "X-aws-ec2-metadata-token").
-define(LINEAR_BACK_OFF_MILLIS, 500).
-define(MAX_RETRIES, 5).
-type access_key() :: nonempty_string().
-type secret_access_key() :: nonempty_string().
-type expiration() :: calendar:datetime() | undefined.
-type security_token() :: nonempty_string() | undefined.
-type region() :: nonempty_string() | undefined.
-type path() :: string().
-type sc_ok() :: {ok, access_key(), secret_access_key(), expiration(), security_token()}.
-type sc_error() :: {error, Reason :: atom()}.
-type security_credentials() :: sc_ok() | sc_error().
-record(imdsv2token, { token :: security_token() | undefined,
expiration :: non_neg_integer() | undefined}).
-type imdsv2token() :: #imdsv2token{}.
-record(state, {access_key :: access_key() | undefined,
secret_access_key :: secret_access_key() | undefined,
expiration :: expiration() | undefined,
security_token :: security_token() | undefined,
region :: region() | undefined,
imdsv2_token:: imdsv2token() | undefined,
error :: atom() | string() | undefined}).
-type state() :: #state{}.
-type scheme() :: atom().
-type username() :: string().
-type password() :: string().
-type host() :: string().
-type tcp_port() :: integer().
-type query_args() :: [tuple() | string()].
-type fragment() :: string().
-type userinfo() :: {undefined | username(),
undefined | password()}.
-type authority() :: {undefined | userinfo(),
host(),
undefined | tcp_port()}.
-record(uri, {scheme :: undefined | scheme(),
authority :: authority(),
path :: undefined | path(),
query :: undefined | query_args(),
fragment :: undefined | fragment()}).
-type method() :: head | get | put | post | trace | options | delete | patch.
-type http_version() :: string().
-type status_code() :: integer().
-type reason_phrase() :: string().
-type status_line() :: {http_version(), status_code(), reason_phrase()}.
-type field() :: string().
-type value() :: string().
-type header() :: {Field :: field(), Value :: value()}.
-type headers() :: [header()].
-type body() :: string() | binary().
-type ssl_options() :: [ssl:tls_client_option()].
-type http_option() :: {timeout, timeout()} |
{connect_timeout, timeout()} |
{ssl, ssl_options()} |
{essl, ssl_options()} |
{autoredirect, boolean()} |
{proxy_auth, {User :: string(), Password :: string()}} |
{version, http_version()} |
{relaxed, boolean()} |
{url_encode, boolean()}.
-type http_options() :: [http_option()].
-record(request, {access_key :: access_key(),
secret_access_key :: secret_access_key(),
security_token :: security_token(),
service :: string(),
region = "us-east-1" :: string(),
method = get :: method(),
headers = [] :: headers(),
uri :: string(),
body = "" :: body()}).
-type request() :: #request{}.
-type httpc_result() :: {ok, {status_line(), headers(), body()}} |
{ok, {status_code(), body()}} |
{error, term()}.
-type result_ok() :: {ok, {ResponseHeaders :: headers(), Response :: list()}}.
-type result_error() :: {'error', Message :: reason_phrase(), {ResponseHeaders :: headers(), Response :: list()} | undefined} |
{'error', {credentials, Reason :: string()}} |
{'error', string()}.
-type result() :: result_ok() | result_error().
|