summaryrefslogtreecommitdiff
path: root/lib/powerdnsex.ex
blob: cc6db9ecdffcec2c0697e342dbf380bbaf22fb2e (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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 get_zone(String.t(), String.t()) :: :ok | {:error, String.t()}
  @doc """
  Show / Retrive info of the specific Zone without RRSets
  """
  def get_zone(zone, server_name \\ @default_server) when is_binary(zone) do
    call({:get_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 put_record(Zone.t(), struct) :: :ok | {:error, String.t()}
  @doc """
  Update Record of the given Zone
  """
  def put_record(%Zone{} = zone, %{} = rrset_attrs) do
    call({:put_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