Packages

AWS client. Currently supports Dynamo, DynamoStreams, EC2, Firehose, Kinesis, KMS, Lambda, RRDS, Route53, S3, SES, SNS, SQS, STS

Current section

Files

Jump to
flex_aws lib ex_aws config auth_cache.ex
Raw

lib/ex_aws/config/auth_cache.ex

defmodule ExAws.Config.AuthCache do
use GenServer
@moduledoc false
# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html
defmodule AuthConfigAdapter do
@moduledoc false
@doc "Compute the awscli auth information."
@callback adapt_auth_config(auth :: map, profile :: String.t(), expiration :: integer) :: any
end
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, :ok, opts)
end
def get(config) do
case :ets.lookup(__MODULE__, :aws_instance_auth) do
[{:aws_instance_auth, auth_config}] -> auth_config
[] -> GenServer.call(__MODULE__, {:refresh_config, config}, 30_000)
end
end
def get(profile, expiration) do
case :ets.lookup(__MODULE__, :awscli) do
[{:awscli, auth_config}] ->
auth_config
[] ->
GenServer.call(__MODULE__, {:refresh_awscli_config, profile, expiration}, 30_000)
end
end
## Callbacks
def init(:ok) do
ets = :ets.new(__MODULE__, [:named_table, read_concurrency: true])
{:ok, ets}
end
def handle_call({:refresh_config, config}, _from, ets) do
auth = refresh_config(config, ets)
{:reply, auth, ets}
end
def handle_call({:refresh_awscli_config, profile, expiration}, _from, ets) do
auth = refresh_awscli_config(profile, expiration, ets)
{:reply, auth, ets}
end
def handle_info({:refresh_config, config}, ets) do
refresh_config(config, ets)
{:noreply, ets}
end
def handle_info({:refresh_awscli_config, profile, expiration}, ets) do
refresh_awscli_config(profile, expiration, ets)
{:noreply, ets}
end
def refresh_awscli_config(profile, expiration, ets) do
Process.send_after(self(), {:refresh_awscli_config, profile, expiration}, expiration)
auth = ExAws.CredentialsIni.security_credentials(profile)
auth =
case ExAws.Config.awscli_auth_adapter() do
nil ->
auth
adapter ->
adapter.adapt_auth_config(auth, profile, expiration)
end
:ets.insert(ets, {:awscli, auth})
auth
end
def refresh_config(config, ets) do
auth = ExAws.InstanceMeta.security_credentials(config)
:ets.insert(ets, {:aws_instance_auth, auth})
Process.send_after(self(), {:refresh_config, config}, refresh_in(auth[:expiration]))
auth
end
def refresh_in(expiration) do
expiration = expiration |> ExAws.Utils.iso_z_to_secs()
time_to_expiration = expiration - ExAws.Utils.now_in_seconds()
# check five mins prior to expiration
refresh_in = time_to_expiration - 5 * 60
# check now if we should have checked in the past
max(0, refresh_in * 1000)
end
end