summaryrefslogtreecommitdiff
path: root/lib/powerdnsex.ex
blob: b77389c2429919b81e9bf81103288a7994f99257 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
defmodule PowerDNSex do
  use Application

  alias PowerDNSex.{Server, Config, Models.Zone, Models.Error}

  @name :PowerDNSex

  def start(_, _), do: start()

  @spec start() :: GenServer.on_start()
  @doc false
  def start do
    children = [:poolboy.child_spec(:pool, pool_config())]
    options = [strategy: :one_for_one, name: :"#{@name}.Supervisor"]

    try do
      Config.valid?()

      case Supervisor.start_link(children, options) do
        {:ok, pid} -> {:ok, pid}
        {:error, {:already_started, pid}} -> {:ok, pid}
        other -> other
      end
    rescue
      error -> {:error, error}
    end
  end

  @default_server "localhost"

  #########
  # Zones #
  #########

  @spec create_zone(Zone.t(), String.t()) :: Zone.t() | Error.t()
  @doc """
  Create a new Zone on PowerDNS
  """
  def create_zone(%Zone{} = zone, server_name \\ @default_server) do
    call({:create_zone, zone, server_name})
  end

  @spec show_zone(String.t(), String.t()) :: :ok | {:error, String.t()}
  @doc """
  Show / Retrive info of the specific Zone
  """
  def show_zone(zone, server_name \\ @default_server) when is_binary(zone) do
    call({:show_zone, zone, server_name})
  end

  @spec delete_zone(String.t(), String.t()) :: :ok | {:error, String.t()}
  @doc """
  Delete specific Zone on PowerDNS
  """
  def delete_zone(zone, server_name \\ @default_server) when is_binary(zone) do
    call({:delete_zone, zone, server_name})
  end

  ###########
  # Records #
  ###########

  @spec create_record(Zone.t(), struct) :: :ok | {:error, String.t()}
  @doc """
  Create a new Record for the given Zone
  """
  def create_record(%Zone{} = zone, %{} = rrset_attrs) do
    call({:create_record, zone, rrset_attrs})
  end

  @spec show_record(String.t(), struct) :: :ok | {:error, String.t()}
  @doc """
  Show / Retrive info of the specific Record of the given Zone name
  """
  def show_record(zone_name, %{} = rrset_attrs) do
    call({:show_record, zone_name, rrset_attrs})
  end

  @spec update_record(Zone.t(), struct) :: :ok | {:error, String.t()}
  @doc """
  Update Record of the given Zone
  """
  def update_record(%Zone{} = zone, %{} = rrset_attrs) do
    call({:update_record, zone, rrset_attrs})
  end

  @spec delete_record(Zone.t(), struct) :: :ok | {:error, String.t()}
  @doc """
  Delete specific Record of given Zone
  """
  def delete_record(%Zone{} = zone, %{} = rrset_attrs) do
    call({:delete_record, zone, rrset_attrs})
  end

  ###########
  # Private #
  ###########

  defp pool_config do
    [
      name: {:local, @name},
      worker_module: Server,
      size: Application.get_env(:powerdnsex, :pool_size, 20),
      max_overflow: Application.get_env(:powerdnsex, :pool_overflow, 8)
    ]
  end

  defp call(params) do
    :poolboy.transaction(@name, fn pid ->
      GenServer.call(pid, params, Config.powerdns_timeout)
    end)
  end
end