Skip to content

Instantly share code, notes, and snippets.

@lubien
Last active April 1, 2023 15:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lubien/c537919416e90a84cfe069be001813ec to your computer and use it in GitHub Desktop.
Save lubien/c537919416e90a84cfe069be001813ec to your computer and use it in GitHub Desktop.

Machines

Mix.install([
  {:kino, "~> 0.8.0"},
  {:tesla, "~> 1.4"},
  {:jason, "~> 1.0"}
])

Settings

fly_token = Kino.Input.password("You Fly Token")
app_name_input = Kino.Input.text("Your Fly app name")

Helpers

defmodule Fly.Machines do
  use Tesla

  plug(Tesla.Middleware.BaseUrl, "https://api.machines.dev/v1")
  plug(Tesla.Middleware.JSON)

  def create_app(client, org_slug, app_name) do
    post(client, "/apps", %{app_name: app_name, org_slug: org_slug})
  end

  def create_machine(client, app_name, config) do
    post(client, "/apps/#{app_name}/machines", %{config: config})
  end

  def allocate_ip(client, app_name, type) do
    """
    mutation ($input: AllocateIPAddressInput!) {
      allocateIpAddress(input: $input) {
        ipAddress {
          address
        }
      }
    }
    """
    |> graphql_request(client, %{input: %{appId: app_name, type: type}})
  end

  def graphql_request(query, client, variables) do
    post(client, "https://api.fly.io/graphql", %{query: query, variables: variables})
  end

  def client(token) do
    middleware = [
      {Tesla.Middleware.Headers, [{"authorization", "Bearer " <> token}]}
    ]

    Tesla.client(middleware)
  end
end
fly_client = Fly.Machines.client(Kino.Input.read(fly_token))
app_name = Kino.Input.read(app_name_input)

Things doing things

{:ok, %{status: 201}} = Fly.Machines.create_app(fly_client, "personal", app_name)
{:ok, %{status: 200}} = Fly.Machines.allocate_ip(fly_client, app_name, "v4")
{:ok, %{status: 200}} = Fly.Machines.allocate_ip(fly_client, app_name, "v6")
secret_key = :crypto.strong_rand_bytes(64) |> Base.encode32(case: :lower) |> :binary.part(0, 64)

config = %{
  image: "flyio/hellofly",
  env: %{
    "PORT" => "8080"
  },
  services: [
    %{
      internal_port: 8080,
      ports: [
        %{
          handlers: [
            "http"
          ],
          port: 80
        },
        %{
          handlers: [
            "tls",
            "http"
          ],
          port: 443
        }
      ],
      protocol: "tcp"
    }
  ],
  checks: %{
    httpget: %{
      type: "http",
      port: 8080,
      method: "GET",
      path: "/",
      interval: "15s",
      timeout: "10s"
    }
  }
}

Fly.Machines.create_machine(fly_client, app_name, config)
IO.puts("https://#{app_name}.fly.dev")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment