137 lines
2.8 KiB
Elixir
137 lines
2.8 KiB
Elixir
defmodule Prymn.Servers do
|
|
@moduledoc """
|
|
The Servers context.
|
|
"""
|
|
|
|
import Ecto.Query, warn: false
|
|
alias Prymn.Repo
|
|
|
|
alias Prymn.Servers.Server
|
|
|
|
@doc """
|
|
Returns the list of servers.
|
|
|
|
## Examples
|
|
|
|
iex> list_servers()
|
|
[%Server{}, ...]
|
|
|
|
"""
|
|
def list_servers do
|
|
Repo.all(Server |> order_by(desc: :inserted_at))
|
|
end
|
|
|
|
@doc """
|
|
Gets a single server.
|
|
|
|
Raises `Ecto.NoResultsError` if the Server does not exist.
|
|
|
|
## Examples
|
|
|
|
iex> get_server!(123)
|
|
%Server{}
|
|
|
|
iex> get_server!(456)
|
|
** (Ecto.NoResultsError)
|
|
|
|
"""
|
|
def get_server!(id), do: Repo.get!(Server, id)
|
|
|
|
@doc """
|
|
Get a single server by its IP.
|
|
"""
|
|
@spec get_server_by_ip!(String.t()) :: Server.t()
|
|
|
|
def get_server_by_ip!(ip), do: Repo.get_by!(Server, public_ip: ip)
|
|
|
|
@doc """
|
|
|
|
Start a new server connection with the app.
|
|
"""
|
|
def create_server(attrs \\ %{}) do
|
|
# Create a unique registration token
|
|
%Server{registration_token: :crypto.strong_rand_bytes(16)}
|
|
|> Server.changeset(attrs)
|
|
|> Repo.insert()
|
|
end
|
|
|
|
@doc """
|
|
Registers a server using a registration token.
|
|
"""
|
|
def register_server(token, public_ip) do
|
|
with true <- :inet.is_ip_address(public_ip),
|
|
{:ok, token} <- Base.decode64(token) do
|
|
public_ip_string =
|
|
public_ip
|
|
|> :inet.ntoa()
|
|
|> to_string()
|
|
|
|
from(s in Server, where: s.registration_token == ^token, select: s)
|
|
|> Repo.one!()
|
|
|> update_server(%{public_ip: public_ip_string, status: :registered})
|
|
else
|
|
false -> {:error, :invalid_ip}
|
|
:error -> {:error, :bad_token}
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Updates a server.
|
|
|
|
## Examples
|
|
|
|
iex> update_server(server, %{field: new_value})
|
|
{:ok, %Server{}}
|
|
|
|
iex> update_server(server, %{field: bad_value})
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def update_server(%Server{} = server, attrs) do
|
|
server
|
|
|> Server.changeset(attrs)
|
|
|> Repo.update()
|
|
end
|
|
|
|
@doc """
|
|
Deletes a server.
|
|
|
|
## Examples
|
|
|
|
iex> delete_server(server)
|
|
{:ok, %Server{}}
|
|
|
|
iex> delete_server(server)
|
|
{:error, %Ecto.Changeset{}}
|
|
|
|
"""
|
|
def delete_server(%Server{} = server) do
|
|
Repo.delete(server)
|
|
end
|
|
|
|
@doc """
|
|
Returns an `%Ecto.Changeset{}` for tracking server changes.
|
|
|
|
## Examples
|
|
|
|
iex> change_server(server)
|
|
%Ecto.Changeset{data: %Server{}}
|
|
|
|
"""
|
|
def change_server(%Server{} = server, attrs \\ %{}) do
|
|
Server.changeset(server, attrs)
|
|
end
|
|
|
|
@doc """
|
|
Returns a string containing the command that needs to be executed to the
|
|
remote server in order to register it to the backend.
|
|
"""
|
|
@spec create_setup_command(Server.t()) :: String.t()
|
|
def create_setup_command(%Server{registration_token: token}) do
|
|
token
|
|
|> Base.encode64()
|
|
|> then(fn token ->
|
|
"wget -O- " <> PrymnWeb.Endpoint.url() <> "/install | sudo sh -s " <> token
|
|
end)
|
|
end
|
|
end
|