Current section

Files

Jump to
ex_aws_lambda lib ex_aws lambda.ex
Raw

lib/ex_aws/lambda.ex

defmodule ExAws.Lambda do
@moduledoc """
Operations on ExAws Lambda
"""
import ExAws.Utils, only: [camelize_key: 1, camelize_keys: 1, upcase: 1]
require Logger
@actions %{
add_permission: :post,
create_event_source_mapping: :post,
create_function: :post,
delete_event_source_mapping: :delete,
delete_function: :delete,
get_event_source_mapping: :get,
get_function: :get,
get_function_configuration: :get,
get_policy: :get,
invoke: :post,
invoke_async: :post,
list_event_source_mappings: :get,
list_functions: :get,
remove_permission: :delete,
update_event_source_mapping: :put,
update_function_code: :put,
update_function_configuration: :put
}
@type starting_position_vals :: :trim_horizon | :latest
@type add_permission_opts :: [
{:source_account, binary} |
{:source_arn, binary}
]
@doc """
Adds a permission to the access policy associated with the specified AWS Lambda function
Action pattern: (lambda:[*]|lambda:[a-zA-Z]+|[*])
"""
@spec add_permission(
function_name :: binary,
principal :: binary,
action :: binary,
statement_id :: binary) :: ExAws.Operation.JSON.t
@spec add_permission(
function_name :: binary,
principal :: binary,
action :: binary,
statement_id :: binary,
opts :: add_permission_opts) :: ExAws.Operation.JSON.t
def add_permission(function_name, principal, action, statement_id, opts \\ []) do
data = opts
|> normalize_opts
|> Map.merge(%{
"Action" => action,
"Principal" => principal,
"StatementId" => statement_id})
request(:add_permission, data, "/2015-03-31/functions/#{function_name}/versions/HEAD/policy")
end
@type create_event_source_mapping_opts :: [
{:batch_size, pos_integer} |
{:enabled, boolean}
]
@doc """
Creates a stream based event source for a function
"""
@spec create_event_source_mapping(
function_name :: binary,
event_source_arn :: binary,
starting_position :: starting_position_vals) :: ExAws.Operation.JSON.t
@spec create_event_source_mapping(
function_name :: binary,
event_source_arn :: binary,
starting_position :: starting_position_vals,
opts :: create_event_source_mapping_opts) :: ExAws.Operation.JSON.t
def create_event_source_mapping(function_name, event_source_arn, starting_position, opts \\ []) do
data = opts
|> normalize_opts
|> Map.merge(%{
"FunctionName" => function_name,
"EventSourceArn" => event_source_arn,
"StartingPosition" => starting_position |> upcase})
request(:create_event_source_mapping, data, "/2015-03-31/event-source-mappings/")
end
@type create_function_opts :: [
{:description, binary} |
{:memory_size, pos_integer} |
{:timeout, pos_integer}
]
@doc """
Create a function.
Runtime defaults to nodejs, as that is the only one available.
"""
@spec create_function(
function_name :: binary,
handler :: binary,
zipfile :: binary) :: ExAws.Operation.JSON.t
@spec create_function(
function_name :: binary,
handler :: binary,
zipfile :: binary,
opts :: create_function_opts) :: ExAws.Operation.JSON.t
def create_function(function_name, handler, zipfile, opts \\ []) do
data = opts
|> normalize_opts
|> Map.merge(%{
"FunctionName" => function_name,
"Handler" => handler,
"Code" => %{"ZipFile" => zipfile}})
request(:create_function, data, "/2015-03-31/functions")
end
@doc "Delete an event source mapping"
@spec delete_event_source_mapping(source_mapping_uuid :: binary) :: ExAws.Operation.JSON.t
def delete_event_source_mapping(source_mapping_uuid) do
request(:delete_event_source_mapping, %{}, "/2015-03-31/event-source-mappings/#{source_mapping_uuid}")
end
@doc "Delete a lambda function"
@spec delete_function(function_name :: binary) :: ExAws.Operation.JSON.t
def delete_function(function_name) do
request(:delete_function, %{}, "/2015-03-31/functions/#{function_name}")
end
@doc "Get an event source mapping"
@spec get_event_source_mapping(source_mapping_uuid :: binary) :: ExAws.Operation.JSON.t
def get_event_source_mapping(source_mapping_uuid) do
request(:get_event_source_mapping, %{}, "/2015-03-31/event-source-mappings/#{source_mapping_uuid}")
end
@doc "Get a function"
@spec get_function(function_name :: binary) :: ExAws.Operation.JSON.t
def get_function(function_name) do
request(:get_function, %{}, "/2015-03-31/functions/#{function_name}/versions/HEAD")
end
@doc "Get a function configuration"
@spec get_function_configuration(function_name :: binary) :: ExAws.Operation.JSON.t
def get_function_configuration(function_name) do
request(:get_function_configuration, %{}, "/2015-03-31/functions/#{function_name}/versions/HEAD/configuration")
end
@doc "Get a function access policy"
@spec get_policy(function_name :: binary) :: ExAws.Operation.JSON.t
def get_policy(function_name) do
request(:get_policy, %{}, "/2015-03-31/functions/#{function_name}/versions/HEAD/policy")
end
@doc "Invoke a lambda function"
@type invoke_opts :: [
{:invocation_type, :event | :request_response | :dry_run} |
{:log_type, :none | :tail} |
{:qualifier, String.t}
]
@spec invoke(function_name :: binary, payload :: map(), client_context :: map()) :: ExAws.Operation.JSON.t
@spec invoke(function_name :: binary, payload :: map(), client_context :: map(), opts :: invoke_opts) :: ExAws.Operation.JSON.t
@context_header "X-Amz-Client-Context"
def invoke(function_name, payload, client_context, opts \\ []) do
{qualifier, opts} = Map.pop(Enum.into(opts, %{}), :qualifier)
headers = [invocation_type: "X-Amz-Invocation-Type", log_type: "X-Amz-Log-Type"]
|> Enum.reduce([], fn({opt, header}, headers) ->
case Map.fetch(opts, opt) do
:error -> headers
{:ok, nil} -> headers
{:ok, value} -> [{header, value |> camelize_key} | headers]
end
end)
headers = case client_context do
%{} ->
headers
context ->
[{@context_header, context} | headers]
end
url = "/2015-03-31/functions/#{function_name}/invocations"
url = if qualifier, do: url <> "?Qualifier=#{qualifier}", else: url
request(:invoke, payload, url, [], headers, fn operation, config ->
headers =
operation.headers
|> List.keyfind(@context_header, 0, nil)
|> case do
nil ->
operation.headers
{_, val} ->
new_val = val |> config.json_codec.encode! |> Base.encode64
List.keyreplace(operation.headers, @context_header, 0, {@context_header, new_val})
end
%{operation | headers: headers}
end)
end
@doc "Invoke a lambda function asynchronously"
@spec invoke_async(function_name :: binary, args :: map()) :: ExAws.Operation.JSON.t
def invoke_async(function_name, args) do
Logger.info("This API is deprecated. See invoke/5 with the Event value set as invocation type")
request(:invoke, args |> normalize_opts, "/2014-11-13/functions/#{function_name}/invoke-async/")
end
@doc "List event source mappings"
@type list_event_source_mappings_opts :: [
{:event_source_arn, binary} |
{:function_name, binary} |
{:marker, binary} |
{:max_items, pos_integer}
]
@spec list_event_source_mappings() :: ExAws.Operation.JSON.t
@spec list_event_source_mappings(opts :: list_event_source_mappings_opts) :: ExAws.Operation.JSON.t
def list_event_source_mappings(opts \\ []) do
params = opts
|> normalize_opts
request(:list_event_source_mappings, %{}, "/2015-03-31/event-source-mappings/", params)
end
@doc "List functions"
@type list_functions_opts :: [
{:marker, binary} |
{:max_items, pos_integer}
]
@spec list_functions() :: ExAws.Operation.JSON.t
@spec list_functions(opts :: list_functions_opts) :: ExAws.Operation.JSON.t
def list_functions(opts \\ []) do
request(:list_functions, %{}, "/2015-03-31/functions/", normalize_opts(opts))
end
@doc "Remove individual permissions from an function's access policy"
@spec remove_permission(function_name :: binary, statement_id :: binary) :: ExAws.Operation.JSON.t
def remove_permission(function_name, statement_id) do
request(:remove_permission, %{}, "/2015-03-31/functions/#{function_name}/versions/HEAD/policy/#{statement_id}")
end
@doc "Update event source mapping"
@spec update_event_source_mapping(uuid :: binary, attrs_to_update :: map()) :: ExAws.Operation.JSON.t
def update_event_source_mapping(uuid, attrs_to_update) do
request(:update_event_source_mapping, attrs_to_update, "/2015-03-31/event-source-mappings/#{uuid}")
end
@doc "Update function code"
@spec update_function_code(function_name :: binary, zipfile :: binary) :: ExAws.Operation.JSON.t
def update_function_code(function_name, zipfile) do
data = %{"ZipFile" => zipfile}
request(:update_function_code, data, "/2015-03-31/functions/#{function_name}/versions/HEAD/code")
end
@doc "Update a function configuration"
@spec update_function_configuration(function_name :: binary, configuration :: map()) :: ExAws.Operation.JSON.t
def update_function_configuration(function_name, configuration) do
data = configuration |> normalize_opts
request(:update_function_configuration, data, "/2015-03-31/functions/#{function_name}/versions/HEAD/configuration")
end
defp normalize_opts(opts) do
opts
|> Map.new
|> camelize_keys
end
defp request(action, data, path, params \\ [], headers \\ [], before_request \\ nil) do
path = [path, "?", params |> URI.encode_query] |> IO.iodata_to_binary
http_method = @actions |> Map.fetch!(action)
ExAws.Operation.JSON.new(:lambda, %{
http_method: http_method,
path: path,
data: data,
headers: [{"content-type", "application/json"} | headers],
before_request: before_request,
})
end
end