Packages

Dead simple Elixir wrapper for the ProfitBricks API.

Current section

Files

Jump to
profitbricks_api_wrapper lib profitbricks.ex
Raw

lib/profitbricks.ex

defmodule ProfitBricks do
@moduledoc """
Documentation for ProfitBricks.
"""
use Tesla, only: [:head, :get, :post, :put, :patch, :delete]
@api_endpoint_default "https://api.profitbricks.com/cloudapi/v4"
@api_endpoint Application.get_env(:profitbricks_api_wrapper, :api_endpoint, @api_endpoint_default)
@username Application.fetch_env!(:profitbricks_api_wrapper, :username)
@password Application.fetch_env!(:profitbricks_api_wrapper, :password)
@http_follow_redirects Application.get_env(:profitbricks_api_wrapper, :http_follow_redirects, true)
@http_retry_enabled Application.get_env(:profitbricks_api_wrapper, :http_retry_enabled, true)
@http_retry_delay Application.get_env(:profitbricks_api_wrapper, :http_retry_delay, 1000)
@http_retry_max_retries Application.get_env(:profitbricks_api_wrapper, :http_retry_max_retries, 5)
@debug_http Application.get_env(:profitbricks_api_wrapper, :debug_http, false)
plug Tesla.Middleware.Tuples, rescue_errors: :all
plug Tesla.Middleware.BaseUrl, @api_endpoint
plug Tesla.Middleware.Headers, make_auth_header()
plug Tesla.Middleware.JSON
plug ForceEmptyBodyAndContentTypeForDelete
if @http_retry_enabled do
plug Tesla.Middleware.Retry, delay: @http_retry_delay, max_retries: @http_retry_max_retries
end
if @http_follow_redirects do
plug Tesla.Middleware.FollowRedirects
end
if @debug_http do
plug Tesla.Middleware.DebugLogger
end
def make_auth_header() do
%{"Authorization" => "Basic " <> Base.encode64(@username <> ":" <> @password)}
end
# ProfitBricks API doesn't allow post requests that are supposed to have no
# data to declare an application/json data content type. So here, build a
# custom, single arg POST function that skips the content type.
def post(path) do
headers = Map.merge(make_auth_header(), %{"Content-Type" => "application/x-www-form-urlencoded"})
response = Tesla.post(@api_endpoint_default <> path, "", headers: headers)
{:ok, response}
rescue
error ->
{:error, error}
end
end
# This is necessary because ProfitBricks API DELETE requests require a
# non-empty Content-Type header, and an empty one is injected by the
# httpc adapter. This overrides the method for DELETE to force a valid
# content type, and passes through non-DELETE requests.
# This can be removed after https://bugs.erlang.org/browse/ERL-536 lands in a
# stable Erlang release.
defmodule ForceEmptyBodyAndContentTypeForDelete do
def call(%{method: :delete, body: nil} = env, next, _opts) do
env = %{env | body: "", headers: Map.put(env.headers, "Content-Type", "text/plain")}
Tesla.run(env, next)
end
def call(env, next, _opts), do: Tesla.run(env, next)
end