Packages
erldns
10.5.2
11.0.2
11.0.1
11.0.0
10.6.0
10.5.6
10.5.5
10.5.4
10.5.3
10.5.2
10.5.1
10.5.0
10.4.4
10.4.3
10.4.2
10.4.1
10.4.0
10.3.0
10.2.1
10.2.0
10.1.0
10.0.0
10.0.0-rc4
10.0.0-rc3
10.0.0-rc2
10.0.0-rc1
9.1.0
9.0.0
9.0.0-rc3
9.0.0-rc2
9.0.0-rc1
8.1.0
8.0.0
8.0.0-rc6
8.0.0-rc5
8.0.0-rc4
8.0.0-rc3
8.0.0-rc2
8.0.0-rc1
7.0.0
7.0.0-rc9
7.0.0-rc8
7.0.0-rc7
7.0.0-rc6
7.0.0-rc5
7.0.0-rc4
7.0.0-rc3
7.0.0-rc2
7.0.0-rc12
7.0.0-rc11
7.0.0-rc10
7.0.0-rc1
6.0.2
6.0.1
6.0.0
5.0.0
4.3.1
4.3.0
4.2.4
4.2.3
4.2.2
4.2.1
4.2.0
4.1.2
4.1.1
4.1.0
4.0.0
3.0.0
1.0.0
Erlang Authoritative DNS Server
Current section
Files
Jump to
Current section
Files
src/admin/erldns_admin_zone_handler.erl
-module(erldns_admin_zone_handler).
-moduledoc """
Support for the erldns Admin API root resource at path `/zones/:name`.
The following is implemented:
- `DELETE`: Deletes a zone from cache.
- `GET`: Returns information about records in a given zone cached in erldns.
Acceps an optional query parameter `metaonly`, that takes a boolean: if set to `true`
only zone metadata is returned, without the actual `"records"`.
The response JSON body looks like the following:
```json
{
"erldns": {
"zone": {
"name": "example.com",
"version": "v1.2.3",
"records_count": 11,
"records": [
{
"name": "example.com.",
"type": "A",
"ttl": 3600,
"content": "1.2.3.4"
},
{
"name": "example.com.",
"type": "AAAA",
"ttl": 3600,
"content": "2001:6A8:0:1:210:4BFF:FE4B:4C61"
},
...
]
}
}
}
```
""".
-behaviour(cowboy_rest).
-include_lib("kernel/include/logger.hrl").
-define(LOG_METADATA, #{domain => [erldns, admin]}).
-export([
init/2,
content_types_provided/2,
resource_exists/2,
allowed_methods/2,
delete_resource/2
]).
-export([to_html/2, to_text/2, to_json/2]).
-doc false.
-spec init(cowboy_req:req(), dynamic()) ->
{cowboy_rest, cowboy_req:req(), dynamic()}.
init(Req, State) ->
{cowboy_rest, Req, State}.
-doc false.
-spec allowed_methods(cowboy_req:req(), dynamic()) ->
{[binary()], cowboy_req:req(), dynamic()}.
allowed_methods(Req, State) ->
{[~"GET", ~"DELETE"], Req, State}.
-doc false.
-spec content_types_provided(cowboy_req:req(), dynamic()) ->
{[{{binary(), binary(), '*'}, atom()}], cowboy_req:req(), dynamic()}.
content_types_provided(Req, State) ->
ContentTypesProvided = [
{{~"application", ~"json", '*'}, to_json},
{{~"text", ~"html", '*'}, to_html},
{{~"text", ~"plain", '*'}, to_text}
],
{ContentTypesProvided, Req, State}.
-doc false.
-spec resource_exists(cowboy_req:req(), dynamic()) ->
{boolean(), cowboy_req:req(), dynamic()}.
resource_exists(Req, State) ->
Name = cowboy_req:binding(zonename, Req),
{erldns_zone_cache:is_in_any_zone(Name), Req, State}.
-doc false.
-spec delete_resource(cowboy_req:req(), dynamic()) ->
{boolean(), cowboy_req:req(), dynamic()}.
delete_resource(Req, State) ->
Name = cowboy_req:binding(zonename, Req),
?LOG_NOTICE(#{what => delete_zone_request, resource => Name}, ?LOG_METADATA),
erldns_zone_cache:delete_zone(Name),
{true, Req, State}.
-doc false.
-spec to_html(cowboy_req:req(), dynamic()) ->
{cowboy_req:resp_body(), cowboy_req:req(), dynamic()}.
to_html(Req, State) ->
{~"erldns admin", Req, State}.
-doc false.
-spec to_text(cowboy_req:req(), dynamic()) ->
{cowboy_req:resp_body(), cowboy_req:req(), dynamic()}.
to_text(Req, State) ->
{~"erldns admin", Req, State}.
-doc false.
-spec to_json(cowboy_req:req(), dynamic()) ->
{stop | cowboy_req:resp_body(), cowboy_req:req(), dynamic()}.
to_json(Req, State) ->
ZoneName = cowboy_req:binding(zonename, Req),
Params = cowboy_req:parse_qs(Req),
?LOG_DEBUG(
#{what => received_get, resource => ZoneName, params => Params},
?LOG_METADATA
),
case erldns_zone_cache:lookup_zone(ZoneName) of
zone_not_found ->
?LOG_ERROR(#{what => get_zone_error, error => zone_not_found}, ?LOG_METADATA),
Resp = "Error getting zone: zone not found",
{stop, cowboy_req:reply(400, #{}, Resp, Req), State};
Zone ->
MaybeMetaOnly = lists:keymember(~"metaonly", 1, Params),
Mode = choose_mode(MaybeMetaOnly),
Json = erldns_zone_codec:encode(Zone, #{mode => Mode}),
Body = json:encode(Json),
{Body, Req, State}
end.
-spec choose_mode(boolean()) -> atom().
choose_mode(true) ->
zone_meta_to_json;
choose_mode(false) ->
zone_to_json.