diff options
author | Tiago Freire <tcfonnet@gmail.com> | 2016-09-05 15:53:08 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-09-05 15:53:08 -0300 |
commit | ace95514385d86132f563fa99673b269e8f6ea26 (patch) | |
tree | 9a4c3f849a2ffbb2138d9a9b6b133c0f5aa2148b /lib | |
parent | Add Delete Record feature (diff) | |
parent | Change mix config (diff) |
Merge pull request #4 from akaKuruma/gen_server
Gen server
Diffstat (limited to 'lib')
-rw-r--r-- | lib/powerdnsex.ex | 103 | ||||
-rw-r--r-- | lib/powerdnsex/config.ex | 9 | ||||
-rw-r--r-- | lib/powerdnsex/gen_server/server.ex | 42 | ||||
-rw-r--r-- | lib/powerdnsex/http_client.ex (renamed from lib/http_client.ex) | 4 | ||||
-rw-r--r-- | lib/powerdnsex/managers/records_manager.ex | 17 | ||||
-rw-r--r-- | lib/powerdnsex/managers/zones_manager.ex | 2 | ||||
-rw-r--r-- | lib/powerdnsex/models/error.ex | 2 | ||||
-rw-r--r-- | lib/powerdnsex/models/record.ex | 8 | ||||
-rw-r--r-- | lib/powerdnsex/models/resource_record_set.ex | 20 | ||||
-rw-r--r-- | lib/powerdnsex/models/zone.ex | 2 |
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 |