summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTiago Freire <code.tiago.frire@locaweb.com.br>2016-08-22 21:26:56 -0300
committerTiago Freire <code.tiago.frire@locaweb.com.br>2016-08-26 14:19:28 -0300
commit416539a6acb4391b52f80d91b96fdab07658953d (patch)
tree6ea82b452f3acfe8f64ef703ed0386b6fca561a4 /lib
parentAdd Delete Record feature (diff)
WIP - Add elixir GenServer
Diffstat (limited to 'lib')
-rw-r--r--lib/powerdnsex.ex68
-rw-r--r--lib/powerdnsex/config.ex7
-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/record.ex8
-rw-r--r--lib/powerdnsex/models/resource_record_set.ex20
-rw-r--r--lib/powerdnsex/server_setup.ex29
8 files changed, 144 insertions, 11 deletions
diff --git a/lib/powerdnsex.ex b/lib/powerdnsex.ex
index c82aa59..7152417 100644
--- a/lib/powerdnsex.ex
+++ b/lib/powerdnsex.ex
@@ -1,2 +1,70 @@
defmodule PowerDNSex do
+ @default_server "localhost"
+ use PowerDNSex.ServerSetup
+
+ alias PowerDNSex.Managers.{ZonesManager, RecordsManager}
+ alias PowerDNSex.Models.Zone
+
+ ###
+ # Zones
+ ###
+
+ @spec create_zone(Zone.t, String.t) :: :ok | {:error, String.t}
+ @doc """
+ Create a new Zone on PowerDNS
+ """
+ def create_zone(%Zone{} = zone, server_name \\ @default_server) do
+ ZonesManager.create(zone, server_name)
+ end
+
+ @spec show_zone(Zone.t, String.t) :: :ok | {:error, String.t}
+ @doc """
+ Show / Retrive info of the specific Zone
+ """
+ def show_zone(%Zone{} = zone, server_name \\ @default_server) do
+ ZonesManager.show(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
+ ZonesManager.delete(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
+ RecordsManager.create(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
+ RecordsManager.show(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
+ RecordsManager.update(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
+ RecordsManager.delete(zone, rrset_attrs)
+ end
end
diff --git a/lib/powerdnsex/config.ex b/lib/powerdnsex/config.ex
index 50589d4..486ccb6 100644
--- a/lib/powerdnsex/config.ex
+++ b/lib/powerdnsex/config.ex
@@ -14,12 +14,11 @@ 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
###
# Private
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/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/server_setup.ex b/lib/powerdnsex/server_setup.ex
new file mode 100644
index 0000000..3b5cb14
--- /dev/null
+++ b/lib/powerdnsex/server_setup.ex
@@ -0,0 +1,29 @@
+defmodule PowerDNSex.ServerSetup do
+ defmacro __using__(opts \\ []) do
+ quote bind_quoted: [opts: opts] do
+ use Application
+
+ @name opts[:process_name] || :PowerDNSex
+ @config opts[:config]
+
+ @spec start(term, term) :: GenServer.on_start
+ def start(_, _), do: start
+
+ @spec start() :: GenServer.on_start
+ @doc false
+ def start do
+ import Supervisor.Spec
+
+ children = [worker(Server, [@name, @config])]
+
+ options = [strategy: :one_for_one, name: :"#{@name}.Supervisor"]
+
+ case Supervisor.start_link(children, options) do
+ {:ok, pid} -> {:ok, pid}
+ {:error, {:already_started, pid}} -> {:ok, pid}
+ other -> other
+ end
+ end
+ end
+ end
+end