Mix.install([
{:kino, "~> 0.8.0"},
{:tesla, "~> 1.4"},
{:jason, "~> 1.0"}
])
fly_token = Kino.Input.password("You Fly Token")
app_name_input = Kino.Input.text("Your Fly app name")
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)
{: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")