Current section
Files
Jump to
Current section
Files
lib/fly_machine_client.ex
defmodule FlyMachineClient do
@moduledoc false
use Tesla
@type response :: {:ok, map() | list(map()) | nil} | {:error, any()}
@type options :: [token: String.t()]
@default_base_url "https://api.machines.dev/v1"
def new(options \\ []) do
middleware = [
{Tesla.Middleware.BaseUrl, base_url()},
{Tesla.Middleware.JSON, engine: Jason},
{Tesla.Middleware.Headers, [{"Authorization", "Bearer #{get_token(options)}"}]},
FlyMachineClient.ErrorHandlerMiddleware
]
adapter = if Mix.env() == :test, do: Tesla.Adapter.Hackney, else: nil
Tesla.client(middleware, adapter)
end
defp get_token(options) do
Keyword.get(options, :token, token())
end
def base_url, do: Application.get_env(:fly_machine_client, :base_url, @default_base_url)
def token do
case Application.get_env(:fly_machine_client, :token) do
nil ->
raise "Fly API token not configured. Please set the :fly_machine_client, :token config value."
token ->
token
end
end
# -----------------------------------------------------
# Low-level direct calls (to Apps, Machines, Secrets, etc.)
# -----------------------------------------------------
@doc """
Lists all apps for the authenticated user.
"""
@spec list_apps(String.t(), options()) :: response()
defdelegate list_apps(org_slug \\ "personal", opts \\ []), to: FlyMachineClient.Apps
@doc """
Creates a new app.
"""
@spec create_app(map(), options()) :: response()
defdelegate create_app(params, opts \\ []), to: FlyMachineClient.Apps
@doc """
Gets details of a specific app.
"""
@spec get_app(String.t(), options()) :: response()
defdelegate get_app(app_name, opts \\ []), to: FlyMachineClient.Apps
@doc """
Destroys (deletes) an app.
"""
@spec destroy_app(String.t(), options()) :: response()
defdelegate destroy_app(app_name, opts \\ []), to: FlyMachineClient.Apps
@doc """
Lists all secrets for a given app.
"""
@spec list_secrets(String.t(), options()) :: response()
defdelegate list_secrets(app_name, opts \\ []), to: FlyMachineClient.Secrets
@doc """
Creates a new secret for an app.
"""
@spec create_secret(String.t(), String.t(), String.t(), [integer()], options()) :: response()
defdelegate create_secret(app_name, secret_label, secret_type, value, opts \\ []),
to: FlyMachineClient.Secrets
@doc """
Generates a new secret for an app.
"""
@spec generate_secret(String.t(), String.t(), String.t(), options()) :: response()
defdelegate generate_secret(app_name, secret_label, secret_type, opts \\ []),
to: FlyMachineClient.Secrets
@doc """
Destroys (deletes) a secret from an app.
"""
@spec destroy_secret(String.t(), String.t(), options()) :: response()
defdelegate destroy_secret(app_name, secret_label, opts \\ []), to: FlyMachineClient.Secrets
# Machine-related functions
@doc """
Lists all machines for a given app.
"""
@spec list_machines(String.t(), options()) :: response()
defdelegate list_machines(app_name, opts \\ []), to: FlyMachineClient.Machines
@doc """
Gets details of a specific machine.
"""
@spec get_machine(String.t(), String.t(), options()) :: response()
defdelegate get_machine(app_name, machine_id, opts \\ []), to: FlyMachineClient.Machines
@doc """
Creates a new machine in a Fly.io app.
"""
@spec create_machine(map(), options()) :: response()
defdelegate create_machine(params, opts \\ []), to: FlyMachineClient.Machines
@doc """
Updates an existing machine in a Fly.io app.
"""
@spec update_machine(map(), options()) :: response()
defdelegate update_machine(params, opts \\ []), to: FlyMachineClient.Machines
@doc """
Destroys (deletes) a machine.
"""
@spec destroy_machine(String.t(), String.t(), options()) :: response()
defdelegate destroy_machine(app_name, machine_id, opts \\ []), to: FlyMachineClient.Machines
@doc """
Restarts a machine.
"""
@spec restart_machine(String.t(), String.t(), options()) :: response()
defdelegate restart_machine(app_name, machine_id, opts \\ []), to: FlyMachineClient.Machines
@doc """
Sends a signal to a machine.
"""
@spec signal_machine(String.t(), String.t(), String.t(), options()) :: response()
defdelegate signal_machine(app_name, machine_id, signal, opts \\ []),
to: FlyMachineClient.Machines
@doc """
Starts a stopped machine.
"""
@spec start_machine(String.t(), String.t(), options()) :: response()
defdelegate start_machine(app_name, machine_id, opts \\ []), to: FlyMachineClient.Machines
@doc """
Stops a running machine.
"""
@spec stop_machine(String.t(), String.t(), options()) :: response()
defdelegate stop_machine(app_name, machine_id, opts \\ []), to: FlyMachineClient.Machines
@doc """
Suspends a running machine.
"""
@spec suspend_machine(String.t(), String.t(), options()) :: response()
defdelegate suspend_machine(app_name, machine_id, opts \\ []), to: FlyMachineClient.Machines
@doc """
Waits for a machine to reach a specific state.
"""
@spec wait_for_machine_state(
String.t(),
String.t(),
String.t(),
String.t(),
integer(),
options()
) ::
response()
defdelegate wait_for_machine_state(
app_name,
machine_id,
instance_id,
state \\ "started",
timeout \\ 60,
opts \\ []
),
to: FlyMachineClient.Machines
@doc """
Lists all volumes associated with a specific app.
"""
@spec list_volumes(String.t(), keyword(), options()) :: response()
defdelegate list_volumes(app_name, opts \\ [], client_opts \\ []),
to: FlyMachineClient.Volumes,
as: :list
@doc """
Creates a volume for a specific app.
"""
@spec create_volume(String.t(), map(), options()) :: response()
defdelegate create_volume(app_name, params, opts \\ []),
to: FlyMachineClient.Volumes,
as: :create
@doc """
Gets details about a specific volume by its ID within an app.
"""
@spec get_volume(String.t(), String.t(), options()) :: response()
defdelegate get_volume(app_name, volume_id, opts \\ []), to: FlyMachineClient.Volumes, as: :get
@doc """
Updates a volume's configuration.
"""
@spec update_volume(String.t(), String.t(), map(), options()) :: response()
defdelegate update_volume(app_name, volume_id, params, opts \\ []),
to: FlyMachineClient.Volumes,
as: :update
@doc """
Deletes a specific volume within an app by volume ID.
"""
@spec delete_volume(String.t(), String.t(), options()) :: response()
defdelegate delete_volume(app_name, volume_id, opts \\ []),
to: FlyMachineClient.Volumes,
as: :delete
@doc """
Extends a volume's size within an app.
"""
@spec extend_volume(String.t(), String.t(), integer(), options()) :: response()
defdelegate extend_volume(app_name, volume_id, size_gb, opts \\ []),
to: FlyMachineClient.Volumes,
as: :extend
@doc """
Lists all snapshots for a specific volume within an app.
"""
@spec list_volume_snapshots(String.t(), String.t(), options()) :: response()
defdelegate list_volume_snapshots(app_name, volume_id, opts \\ []),
to: FlyMachineClient.Volumes,
as: :list_snapshots
@doc """
Creates a snapshot for a specific volume within an app.
"""
@spec create_volume_snapshot(String.t(), String.t(), options()) :: response()
defdelegate create_volume_snapshot(app_name, volume_id, opts \\ []),
to: FlyMachineClient.Volumes,
as: :create_snapshot
# -----------------------------------------------------
# Higher-level orchestrations
# -----------------------------------------------------
@doc """
Creates an app, then waits for it to become active (polling get_app).
"""
@spec create_app_and_wait(map(), keyword()) :: response()
defdelegate create_app_and_wait(params, wait_opts \\ []),
to: FlyMachineClient.Orchestrator
@doc """
Creates a machine, then waits for it to reach "started" state.
"""
@spec create_machine_and_wait(map(), keyword()) :: response()
defdelegate create_machine_and_wait(params, wait_opts \\ []),
to: FlyMachineClient.Orchestrator
end