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