summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTiago Freire <tcfonnet@gmail.com>2016-08-16 01:18:30 -0300
committerTiago Freire <code.tiago.frire@locaweb.com.br>2016-08-16 19:02:58 -0300
commit217482d28f9125cc7a0034896da7a75b9e64ca41 (patch)
tree17335246dd2b76e4ffa2f1b3237715b67bfa1242 /lib
parent[WIP] Init. (diff)
WIP
Diffstat (limited to 'lib')
-rw-r--r--lib/http_client.ex4
-rw-r--r--lib/powerdnsex/config.ex (renamed from lib/powerdnsx/config.ex)6
-rw-r--r--lib/powerdnsex/managers/records_manager.ex30
-rw-r--r--lib/powerdnsex/managers/zones_manager.ex46
-rw-r--r--lib/powerdnsex/models/error.ex3
-rw-r--r--lib/powerdnsex/models/record.ex9
-rw-r--r--lib/powerdnsex/models/resource_record_set.ex20
-rw-r--r--lib/powerdnsex/models/zone.ex28
-rw-r--r--lib/powerdnsx.ex2
-rw-r--r--lib/powerdnsx/managers/zones_manager.ex40
-rw-r--r--lib/powerdnsx/models/zone.ex25
-rw-r--r--lib/powerdnsx/validations/zone_validation.ex38
12 files changed, 142 insertions, 109 deletions
diff --git a/lib/http_client.ex b/lib/http_client.ex
index d819087..6d18cbe 100644
--- a/lib/http_client.ex
+++ b/lib/http_client.ex
@@ -1,11 +1,11 @@
-defmodule PowerDNSx.HttpClient do
+defmodule PowerDNSex.HttpClient do
@moduledoc"""
Client to do http requests for PowerDns API
"""
use HTTPoison.Base
- alias PowerDNSx.Config
+ alias PowerDNSex.Config
def process_url(url) do
Config.powerdns_url <> url
diff --git a/lib/powerdnsx/config.ex b/lib/powerdnsex/config.ex
index d172fa9..50589d4 100644
--- a/lib/powerdnsx/config.ex
+++ b/lib/powerdnsex/config.ex
@@ -1,8 +1,8 @@
-defmodule PowerDNSx.Config do
+defmodule PowerDNSex.Config do
defstruct url: "",
token: ""
- alias PowerDNSx.Config
+ alias PowerDNSex.Config
def data do
set_attr_value = &(Map.put(&2, &1, get_key(&1)))
@@ -30,7 +30,7 @@ defmodule PowerDNSx.Config do
{:ok, {:system, env_var_name}} -> System.get_env(env_var_name)
{:ok, value} -> value
_ ->
- raise "[PowerDNSx] PowerDNS #{Atom.to_string(key)} not configured."
+ raise "[PowerDNSex] PowerDNS #{Atom.to_string(key)} not configured."
end
end
end
diff --git a/lib/powerdnsex/managers/records_manager.ex b/lib/powerdnsex/managers/records_manager.ex
new file mode 100644
index 0000000..7d580b2
--- /dev/null
+++ b/lib/powerdnsex/managers/records_manager.ex
@@ -0,0 +1,30 @@
+defmodule PowerDNSex.RecordsManager do
+
+ alias PowerDNSex.HttpClient
+ alias PowerDNSex.Models.{Zone, Record, Error}
+ alias PowerDNSex.Models.ResourceRecordSet, as: RRset
+ alias HTTPoison.Response
+
+ def create(%Zone{url: nil}, _) do
+ raise "[Records Manager] Zone URL attribute is empty!"
+ end
+
+ def create(%Zone{} = zone, %{} = rrset) do
+ rrset = %{rrset | changetype: "REPLACE"}
+
+ zone.url
+ |> HttpClient.patch!(rrset.as_body(rrset))
+ |> process_request_response
+ end
+
+ ###
+ # Private
+ ##
+
+ defp process_request_response(%Response{body: body, status_code: status}) do
+ case status do
+ s when s < 300 -> :ok
+ s when s >= 300 -> body |> Poison.decode!(as: %Error{})
+ end
+ end
+end
diff --git a/lib/powerdnsex/managers/zones_manager.ex b/lib/powerdnsex/managers/zones_manager.ex
new file mode 100644
index 0000000..e511ac1
--- /dev/null
+++ b/lib/powerdnsex/managers/zones_manager.ex
@@ -0,0 +1,46 @@
+defmodule PowerDNSex.ZonesManager do
+
+ @default_server "localhost"
+
+ alias PowerDNSex.HttpClient
+ alias PowerDNSex.Models.{Zone, Error, ResourceRecordSet, Record}
+ alias HTTPoison.Response
+
+ def create(%Zone{} = zone, server_name \\ @default_server) do
+ zone_path(server_name)
+ |> HttpClient.post!(Zone.as_body(zone))
+ |> process_request_response
+ end
+
+ def show(zone_name, server_name \\ @default_server)
+ when is_bitstring(zone_name) do
+
+ zone_path(server_name, zone_name)
+ |> HttpClient.get!
+ |> process_request_response
+ end
+
+ ###
+ # Private
+ ###
+
+ defp zone_path(server_name) when is_bitstring(server_name) do
+ "api/v1/servers/#{server_name}/zones"
+ end
+
+ defp zone_path(server_name, zone_name) when is_bitstring(server_name) do
+ zone_path(server_name) <> "/#{zone_name}"
+ end
+
+ defp process_request_response(%Response{body: body, status_code: status}) do
+ case status do
+ s when s < 300 ->
+ body |> Poison.decode!(as: %Zone{rrsets: [
+ %ResourceRecordSet{
+ records: [%Record{}]
+ }]})
+ s when s >= 300 ->
+ body |> Poison.decode!(as: %Error{})
+ end
+ end
+end
diff --git a/lib/powerdnsex/models/error.ex b/lib/powerdnsex/models/error.ex
new file mode 100644
index 0000000..1cf9f62
--- /dev/null
+++ b/lib/powerdnsex/models/error.ex
@@ -0,0 +1,3 @@
+defmodule PowerDNSex.Models.Error do
+ defstruct [:error]
+end
diff --git a/lib/powerdnsex/models/record.ex b/lib/powerdnsex/models/record.ex
new file mode 100644
index 0000000..82dca74
--- /dev/null
+++ b/lib/powerdnsex/models/record.ex
@@ -0,0 +1,9 @@
+defmodule PowerDNSex.Models.Record do
+ defstruct [:content, :disabled]
+
+ def as_body(content) when is_list(content) do
+ Enum.reduce(content, [], fn({value, status}, records) ->
+ records ++ [%__MODULE__{ content: value, disabled: status }]
+ end)
+ end
+end
diff --git a/lib/powerdnsex/models/resource_record_set.ex b/lib/powerdnsex/models/resource_record_set.ex
new file mode 100644
index 0000000..a3bca8d
--- /dev/null
+++ b/lib/powerdnsex/models/resource_record_set.ex
@@ -0,0 +1,20 @@
+defmodule PowerDNSex.Models.ResourceRecordSet do
+
+ alias PowerDNSex.Models.Record
+
+ defstruct [:name, :type, :ttl, :records, :changetype]
+
+ def as_body(%__MODULE__{} = record) do
+ %{ rrsets: [
+ %{
+ name: record.name,
+ type: record.type,
+ ttl: record.ttl,
+ changetype: record.changetype,
+ records: Record.as_body(record.content)
+ }
+ ]}
+ |> Poison.encode!
+ end
+
+end
diff --git a/lib/powerdnsex/models/zone.ex b/lib/powerdnsex/models/zone.ex
new file mode 100644
index 0000000..62a5a2a
--- /dev/null
+++ b/lib/powerdnsex/models/zone.ex
@@ -0,0 +1,28 @@
+defmodule PowerDNSex.Models.Zone do
+ @moduledoc """
+ Model for PowerDns zones, create and validate format
+ """
+
+ @body_attrs ~w(account dns kind masters name nameservers records serial
+ soa_edit soa_edit_api)a
+
+ defstruct name: nil, kind: "Native", masters: [], nameservers: [], rrsets: [],
+ account: nil, comments: [], dnssec: false, id: nil, last_check: 0,
+ notified_serial: 0, serial: nil, soa_edit: "", soa_edit_api: "",
+ url: nil
+
+ def as_body(%__MODULE__{} = zone) do
+ get_valid_attrs = fn({attr, value}, body) ->
+ if Enum.member?(@body_attrs, attr) do
+ Map.merge(body, %{attr => value})
+ else
+ body
+ end
+ end
+
+ zone
+ |> Map.from_struct
+ |> Enum.reduce(%{}, get_valid_attrs)
+ |> Poison.encode!
+ end
+end
diff --git a/lib/powerdnsx.ex b/lib/powerdnsx.ex
index 711fde6..c82aa59 100644
--- a/lib/powerdnsx.ex
+++ b/lib/powerdnsx.ex
@@ -1,2 +1,2 @@
-defmodule PowerDNSx do
+defmodule PowerDNSex do
end
diff --git a/lib/powerdnsx/managers/zones_manager.ex b/lib/powerdnsx/managers/zones_manager.ex
deleted file mode 100644
index 6e313d6..0000000
--- a/lib/powerdnsx/managers/zones_manager.ex
+++ /dev/null
@@ -1,40 +0,0 @@
-defmodule PowerDNSx.ZonesManager do
-
- @default_server "localhost"
-
- alias PowerDNSx.HttpClient
- alias HTTPoison.Response, as: PoisonResp
- alias PowerDNSx.Models.Zone
-
- def create(%Zone{} = zone, server_name \\ @default_server) do
- case Zone.is_valid?(zone) do
- true ->
- zone_path(server_name)
- |> HttpClient.post!(zone)
- |> process_request_response
- {false, errors} -> {:error, errors}
- end
- end
-
- def show(zone_name, server_name \\ @default_server) when is_bitstring(zone_name) do
- zone_path(server_name, zone_name)
- |> HttpClient.get!
- |> process_request_response
- end
-
- ###
- # Private
- ###
-
- defp zone_path(server_name) when is_bitstring(server_name) do
- "/servers/#{server_name}/zones"
- end
-
- defp zone_path(server_name, zone_name) when is_bitstring(server_name) do
- zone_path(server_name) <> "/#{zone_name}"
- end
-
- defp process_request_response(%PoisonResp{body: body, status_code: status} ) do
- body |> Poison.decode!(as: %Zone{})
- end
-end
diff --git a/lib/powerdnsx/models/zone.ex b/lib/powerdnsx/models/zone.ex
deleted file mode 100644
index b2a9249..0000000
--- a/lib/powerdnsx/models/zone.ex
+++ /dev/null
@@ -1,25 +0,0 @@
-defmodule PowerDNSx.Models.Zone do
- @moduledoc """
- Model for PowerDns zones, create and validate format
- """
-
- @valid_hostname_regex ~r/^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$/
-
- defstruct name: nil,
- kind: "Native",
- masters: [],
- nameservers: [],
- records: [],
- account: nil,
- comments: [],
- dnssec: false,
- id: nil,
- last_check: 0,
- notified_serial: 0,
- serial: nil,
- soa_edit: "",
- soa_edit_api: "",
- url: nil
-
-
-end
diff --git a/lib/powerdnsx/validations/zone_validation.ex b/lib/powerdnsx/validations/zone_validation.ex
deleted file mode 100644
index a2abc6e..0000000
--- a/lib/powerdnsx/validations/zone_validation.ex
+++ /dev/null
@@ -1,38 +0,0 @@
-defmodule PowerDNSx.ZoneValidator do
- alias PowerDNSx.Models.Zone
-
- @valid_zone_name_reg ~r/^(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])$/
-
- def check(%Zone{} = zone) do
- verify_attr = fn({attr, value}, errors)->
- validate_attr_value(attr, value)
- end
-
- errors = Enum.reduce(zone, nil, verify_attr)
- if errors, do: {:error, errors}, else: :ok
- end
-
- ###
- # Private
- ###
-
- defp validate_attr_value(:name, zone_name) do
- case validate_zone_name(zone_name) do
- {true, true} -> nil
- {false, _} -> {:error, %{name: "#{zone_name} is invalid."}}
- {_, false} -> {:error, %{name: "#{zone_name} is invalid. Max lenght is 64."}}
- {:format_error} -> {:error, %{name: "Name MUST be a string."}}
- end
- end
-
- defp validate_zone_name(zone_name) when is_bitstring(zone_name) do
- {String.match?(zone_name, @valid_zone_name_reg), correct_length?(zone_name)}
- end
-
- defp validate_zone_name(_), do: {:format_error}
-
- defp correct_length?(zone_name) do
- name = zone_name |> String.split(".") |> hd
- name |> String.length <= 63
- end
-end