summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTiago Freire <tcfonnet@gmail.com>2016-09-05 15:53:08 -0300
committerGitHub <noreply@github.com>2016-09-05 15:53:08 -0300
commitace95514385d86132f563fa99673b269e8f6ea26 (patch)
tree9a4c3f849a2ffbb2138d9a9b6b133c0f5aa2148b /lib
parentAdd Delete Record feature (diff)
parentChange mix config (diff)
Merge pull request #4 from akaKuruma/gen_server
Gen server
Diffstat (limited to 'lib')
-rw-r--r--lib/powerdnsex.ex103
-rw-r--r--lib/powerdnsex/config.ex9
-rw-r--r--lib/powerdnsex/gen_server/server.ex42
-rw-r--r--lib/powerdnsex/http_client.ex (renamed from lib/http_client.ex)4
-rw-r--r--lib/powerdnsex/managers/records_manager.ex17
-rw-r--r--lib/powerdnsex/managers/zones_manager.ex2
-rw-r--r--lib/powerdnsex/models/error.ex2
-rw-r--r--lib/powerdnsex/models/record.ex8
-rw-r--r--lib/powerdnsex/models/resource_record_set.ex20
-rw-r--r--lib/powerdnsex/models/zone.ex2
10 files changed, 198 insertions, 11 deletions
diff --git a/lib/powerdnsex.ex b/lib/powerdnsex.ex
index c82aa59..0114f6f 100644
--- a/lib/powerdnsex.ex
+++ b/lib/powerdnsex.ex
@@ -1,2 +1,105 @@
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
+ import Supervisor.Spec
+
+ children = [worker(Server, [@name])]
+ 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(Zone.t, String.t) :: :ok | {:error, String.t}
+ @doc """
+ Delete specific Zone on PowerDNS
+ """
+ def delete_zone(%Zone{} = zone, server_name \\ @default_server) 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(Zone.t, struct) :: :ok | {:error, String.t}
+ @doc """
+ Show / Retrive info of the specific Record of the given Zone
+ """
+ def show_record(%Zone{} = zone, %{} = rrset_attrs) do
+ call({:show_record, zone, 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 call(params), do: GenServer.call(@name, params)
+
end
diff --git a/lib/powerdnsex/config.ex b/lib/powerdnsex/config.ex
index 50589d4..2cf55f1 100644
--- a/lib/powerdnsex/config.ex
+++ b/lib/powerdnsex/config.ex
@@ -14,12 +14,13 @@ defmodule PowerDNSex.Config do
end
def powerdns_url do
- data.url
+ url = data.url
+ if String.ends_with?(url, "/"), do: url, else: url <> "/"
end
- def powerdns_token do
- data.token
- end
+ def powerdns_token, do: data.token
+
+ def valid?(), do: powerdns_url && powerdns_token
###
# Private
diff --git a/lib/powerdnsex/gen_server/server.ex b/lib/powerdnsex/gen_server/server.ex
new file mode 100644
index 0000000..52768b3
--- /dev/null
+++ b/lib/powerdnsex/gen_server/server.ex
@@ -0,0 +1,42 @@
+defmodule PowerDNSex.Server do
+ use GenServer
+
+ alias PowerDNSex.Managers.{ZonesManager, RecordsManager}
+ alias PowerDNSex.Models.Zone
+
+ def start_link(name) do
+ GenServer.start_link(__MODULE__, :ok, name: name)
+ end
+
+ ###
+ # Zones
+ ###
+
+ def handle_call({:create_zone, zone, server_name}, _from, state) do
+ {:reply, ZonesManager.create(zone, server_name), state}
+ end
+
+ def handle_call({:show_zone, zone, server_name}, _from, state) do
+ {:reply, ZonesManager.show(zone, server_name), state}
+ end
+
+ def handle_call({:delete_zone, zone, server_name}, _from, state) do
+ {:reply, ZonesManager.delete(zone, server_name), state}
+ end
+
+ def handle_call({:create_record, zone, rrset_attrs}, _from, state) do
+ {:reply, RecordsManager.create(zone, rrset_attrs), state}
+ end
+
+ def handle_call({:show_record, zone, rrset_attrs}, _from, state) do
+ {:reply, RecordsManager.show(zone, rrset_attrs), state}
+ end
+
+ def handle_call({:update_record, zone, rrset_attrs}, _from, state) do
+ {:reply, RecordsManager.update(zone, rrset_attrs), state}
+ end
+
+ def handle_call({:delete_record, zone, rrset_attrs}, _from, state) do
+ {:reply, RecordsManager.delete(zone, rrset_attrs), state}
+ end
+end
diff --git a/lib/http_client.ex b/lib/powerdnsex/http_client.ex
index 6d18cbe..0a242b5 100644
--- a/lib/http_client.ex
+++ b/lib/powerdnsex/http_client.ex
@@ -7,9 +7,7 @@ defmodule PowerDNSex.HttpClient do
alias PowerDNSex.Config
- def process_url(url) do
- Config.powerdns_url <> url
- end
+ def process_url(url), do: Config.powerdns_url <> url
defp process_request_headers(headers) do
custom = ["X-API-Key": Config.powerdns_token]
diff --git a/lib/powerdnsex/managers/records_manager.ex b/lib/powerdnsex/managers/records_manager.ex
index 7ac83ca..a8c67e5 100644
--- a/lib/powerdnsex/managers/records_manager.ex
+++ b/lib/powerdnsex/managers/records_manager.ex
@@ -1,8 +1,9 @@
-defmodule PowerDNSex.RecordsManager do
+defmodule PowerDNSex.Managers.RecordsManager do
alias PowerDNSex.HttpClient
alias PowerDNSex.Models.{Zone, Record, Error}
- alias PowerDNSex.Models.ResourceRecordSet, as: RRset
+ alias PowerDNSex.Models.ResourceRecordSet, as: RRSet
+ alias PowerDNSex.Managers.ZonesManager
alias HTTPoison.Response
@@ -11,6 +12,11 @@ defmodule PowerDNSex.RecordsManager do
patch(zone, rrset_attrs)
end
+ def show(zone_name, %{} = rrset_attrs) do
+ zone = ZonesManager.show(zone_name)
+ RRSet.find(zone.rrsets, rrset_attrs)
+ end
+
def update(%Zone{} = zone, %{} = rrset_attrs) do
rrset_attrs = Map.merge(rrset_attrs, %{changetype: "REPLACE"})
patch(zone, rrset_attrs)
@@ -38,7 +44,12 @@ defmodule PowerDNSex.RecordsManager do
defp patch(%Zone{} = zone, %{} = rrset_attrs) do
zone.url
- |> HttpClient.patch!(RRset.as_body(RRset.build(rrset_attrs)))
+ |> HttpClient.patch!(RRSet.as_body(RRSet.build(rrset_attrs)))
|> process_request_response
end
+
+ defp has_attrs?(rrset, attrs) do
+ Map.keys(attrs)
+ |> Enum.all?(&(equal_attr?(&1, attrs[&1], rrsets)))
+ end
end
diff --git a/lib/powerdnsex/managers/zones_manager.ex b/lib/powerdnsex/managers/zones_manager.ex
index ebad7fe..260adbb 100644
--- a/lib/powerdnsex/managers/zones_manager.ex
+++ b/lib/powerdnsex/managers/zones_manager.ex
@@ -1,4 +1,4 @@
-defmodule PowerDNSex.ZonesManager do
+defmodule PowerDNSex.Managers.ZonesManager do
@default_server "localhost"
diff --git a/lib/powerdnsex/models/error.ex b/lib/powerdnsex/models/error.ex
index 1cf9f62..d4b1183 100644
--- a/lib/powerdnsex/models/error.ex
+++ b/lib/powerdnsex/models/error.ex
@@ -1,3 +1,5 @@
defmodule PowerDNSex.Models.Error do
defstruct [:error]
+
+ @type t :: %__MODULE__{error: String.t}
end
diff --git a/lib/powerdnsex/models/record.ex b/lib/powerdnsex/models/record.ex
index a494a07..9ffc2b7 100644
--- a/lib/powerdnsex/models/record.ex
+++ b/lib/powerdnsex/models/record.ex
@@ -26,4 +26,12 @@ defmodule PowerDNSex.Models.Record do
def as_body(record_attrs) when is_tuple(record_attrs) do
%{content: elem(record_attrs, 0), disabled: elem(record_attrs, 1)}
end
+
+ def find(records, attrs) when is_list(records) do
+ Enum.find(records, fn(record)->
+ Enum.all?(attrs, fn({attr, attr_value})->
+ Map.get(record, attr) == attr_value
+ end)
+ end)
+ end
end
diff --git a/lib/powerdnsex/models/resource_record_set.ex b/lib/powerdnsex/models/resource_record_set.ex
index f4338a2..9f248ab 100644
--- a/lib/powerdnsex/models/resource_record_set.ex
+++ b/lib/powerdnsex/models/resource_record_set.ex
@@ -25,6 +25,22 @@ defmodule PowerDNSex.Models.ResourceRecordSet do
|> Poison.encode!
end
+ def find(rrsets, %{} = attrs) when is_list(rrsets) do
+ Enum.find(rrsets, fn(rrset)->
+ Enum.all?(attrs, fn({attr, attr_value})->
+ if Enum.member?(Map.keys(%__MODULE__{}), attr) do
+ equal_attr?(attr, attr_value, rrset)
+ else
+ Record.find(rrset.records, %{attr => attr_value})
+ end
+ end)
+ end)
+ end
+
+ ###
+ # Private
+ ###
+
defp set_attrs(rrset, attr_name, attrs) do
if Map.has_key?(attrs, attr_name) do
attr_value = case attr_name do
@@ -37,4 +53,8 @@ defmodule PowerDNSex.Models.ResourceRecordSet do
rrset
end
end
+
+ defp equal_attr?(attr, attr_value, rrset) do
+ Map.get(rrset, attr) == attr_value
+ end
end
diff --git a/lib/powerdnsex/models/zone.ex b/lib/powerdnsex/models/zone.ex
index 62a5a2a..8620443 100644
--- a/lib/powerdnsex/models/zone.ex
+++ b/lib/powerdnsex/models/zone.ex
@@ -11,6 +11,8 @@ defmodule PowerDNSex.Models.Zone do
notified_serial: 0, serial: nil, soa_edit: "", soa_edit_api: "",
url: nil
+ @type t :: %__MODULE__{}
+
def as_body(%__MODULE__{} = zone) do
get_valid_attrs = fn({attr, value}, body) ->
if Enum.member?(@body_attrs, attr) do